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