编程语言
首页 > 编程语言> > java – 为每个应用于所有项而不是仅1设置内部条件的值

java – 为每个应用于所有项而不是仅1设置内部条件的值

作者:互联网

我在这里有一个非常奇怪的问题,我在列表内的对象内部迭代迭代的问题,并且有一个条件,问题是第二次迭代具有设置值的条件但是它适用于所有项目,即使条件是假.

我有以下课程:

EventFeedKey(用作hashmap的键):

public class EventFeedKey {
    private final int eventId;
    private final int triggerId;

    public EventFeedKey(int eventId, int triggerId) {
        this.eventId = eventId;
        this.triggerId = triggerId;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof EventFeedKey)) {
            return false;
        }

        EventFeedKey otherKey = (EventFeedKey) object;
        return this.eventId == otherKey.eventId && this.triggerId == otherKey.triggerId;
    }

    @Override
    public int hashCode() {
        int result = 17; // any prime number
        result = 31 * result + Integer.valueOf(this.eventId).hashCode();
        result = 31 * result + Integer.valueOf(this.triggerId).hashCode();
        return result;
    }
}

事件:

@Entity
@Table(name = "events")
public class Event {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(nullable = false)
    private String title;

    @ManyToOne(optional = false)
    @JoinColumn(name = "type_id")
    private EventType type;

// Setters and Getters
}

事件类型:

@Entity
@Table(name = "event_types")
public class EventType {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(nullable = false)
    private String title;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "eventType", cascade = CascadeType.ALL)
    @JsonManagedReference  
    private List<EventTypeTrigger> triggers = new ArrayList<>();

// Setters and Getters
}

EventTypeTrigger:

@Entity
@Table(name = "event_type_triggers")
public class EventTypeTrigger  {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(nullable = false)
    private String title;

    @Transient
    private int count;

// Setters and Getters
}

以下必须返回列表,触发器填充来自triggersFeed的计数值.

    List<Event> eventList = new ArrayList<Event>();
    if (eventList != null) {
        HashMap<EventFeedKey, Integer> triggersFeed = getTriggersWithCounts();
        eventList.stream().forEach(event -> {
            event.getType().getTriggers().stream().forEach(eventTypeTrigger -> {
                EventFeedKey key = new EventFeedKey(event.getId(), eventTypeTrigger.getId());
                eventTypeTrigger.setCount(triggersFeed.get(key) != null ? (Integer) triggersFeed.get(key) : 0);
            });
        });
        return eventList;
    }

在getTriggersWithCounts()里面:

public HashMap<EventFeedKey, Integer> getTriggersWithCounts() {
    HashMap<EventFeedKey, Integer> eventTriggers = new HashMap<>();
    // event id : 1, trigger id 7
    eventTriggers.put(new EventFeedKey(1,7), 5);
    return eventTriggers;
}

让我说我有以下数据:

对于eventList:

[  
   {  "id":1, "title":"Team A vs Team X", 
      "type":{  
         "id":3,
         "title":"Baseball",
         "triggers":[  
            {  
               "id":7,
               "title":"Base Reached",
               "count":0
            },
            {  
               "id":8,
               "title":"Out",
               "count":0
            }
         ]
      }
   },
      {  
      "id":2, "title":"Team A vs Team C",
      "type":{  
         "id":3,
         "title":"Baseball",
         "triggers":[  
            {  
               "id":7,
               "title":"Base Reached",
               "count":0
            },
            {  
               "id":8,
               "title":"Out",
               "count":0
            }
         ]
      }
   },
]

我从该方法得到的结果(这是错误的)是:

[  
   {  "id":1, "title":"Team A vs Team X", 
      "type":{  
         "id":3,
         "title":"Baseball",
         "triggers":[  
            {  
               "id":7,
               "title":"Base Reached",
               "count":5
            },
            {  
               "id":8,
               "title":"Out",
               "count":0
            }
         ]
      }
   },
      {  
      "id":2, "title":"Team A vs Team C",
      "type":{  
         "id":3,
         "title":"Baseball",
         "triggers":[  
            {  
               "id":7,
               "title":"Base Reached",
               "count":5
            },
            {  
               "id":8,
               "title":"Out",
               "count":0
            }
         ]
      }
   },
]

最烦人的,如果我加上这个:

if (triggersFeed.get(key) != null) {
    System.out.print(triggersFeed.get(key).toString());
}

它只打印出一个结果!

问题是:为什么id:2的事件被修改了?

编辑:
我认为现在的问题与我在Playframework中使用的Ebean:http://ebean-orm.github.io/有关.

解决方法:

首先,感谢@ArturBiesiadowski的提示,问题只是来自Ebean,它引用了实体实例,因为它们具有相同的@Id,所以即使我为1个实体设置了值,但是当我得到实体时我获得相同的实例,即使我没有坚持那个实体,并且在我检索列表之前它们是不同的,但是当我在修改后得到列表时,Ebean似乎得到了带有getter的修改后的实体.

解决方案只是使用其他对象(如DTO),我之前已经拥有它们,但是我修改了列表然后返回DTO,我做了什么我将列表转换为DTO然后修改了列表,这样做了有用.

我使用http://mapstruct.org/在实体和DTO之间进行映射,我的DTO类与实体类相同但没有注释.

EventDTO:

public class EventDTO {
    private Integer id;
    private String title;
    private EventTypeDTO type;

// Setters and Getters
}

EventTypeDTO:

public class EventTypeDTO {
    private Integer id;
    private String title;
    private List<EventTypeTriggerDTO> triggers = new ArrayList<>();

// Setters and Getters
}

EventTypeTriggerDTO:

public class EventTypeTriggerDTO  {
    private Integer id;
    private String title;
    private int count;

// Setters and Getters
}

现在的代码是:

    List<Event> eventList = new ArrayList<Event>();

    if (eventList != null) {
        List<EventDTO> eventDTOList = new ArrayList<>(EventMapper.INSTANCE.map(eventList));
        HashMap<EventFeedKey, Integer> triggersFeed = getTriggersWithCounts();
        eventList.stream().forEach(event -> {
            event.getType().getTriggers().stream().forEach(eventTypeTrigger -> {
                EventFeedKey key = new EventFeedKey(event.getId(), eventTypeTrigger.getId());
                eventTypeTrigger.setCount(triggersFeed.get(key) != null ? (Integer) triggersFeed.get(key) : 0);
            });
        });
        return eventDTOList;
    }

当然你需要去Mappers的MapStruct文档,但是如果你不想使用maplayer的mapper,那么想法只是将实体类映射到DTO类,使用你想要的任何Mapper,但我确定的是MapStruct在这种情况下运行良好.

标签:java,for-loop,playframework,ebean
来源: https://codeday.me/bug/20190711/1431087.html