【发布时间】:2016-04-28 17:02:15
【问题描述】:
我在这里有一个非常奇怪的问题,我在列表中的对象内对列表进行迭代的问题,并且有一个条件,问题是第二次迭代有条件设置值,但它甚至适用于所有项目如果条件为假。
我有以下课程:
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
}
事件类型触发器:
@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 的事件?
编辑: 我认为这个问题现在与 Ebean 相关:http://ebean-orm.github.io/ 我在 Playframework 中使用。
【问题讨论】:
-
您是如何构建数据的?我的感觉是,您在两个 Event 实例中都有指向相同 EventType 的指针,当您从一个事件更新它时,它是另一个 Event 中存在的同一个对象
-
@ArturBiesiadowski 这些是我从数据库中获得的实体,我还有另一个列表,但在 1 级(不是嵌套循环)中没有这样的问题。我在考虑指针,但在调试中我没有看到这个。
-
我执行了您提供的示例(手动构造了每个输入事件)并且输出完全符合预期(仅修改了事件 id=1 的 EventTypeTrigger id=7)。几乎可以肯定,您可能会遇到两个事件中使用相同 EventTypeTrigger 对象的问题。
-
好吧,调试对象的问题看起来如此不同,甚至没有意义,有实体,我正在使用带有 ebean 的播放框架
-
@ArturBiesiadowski 谢谢,我明白了,你说的提示让我照顾 ebean 框架,这是问题所在,ebean 是引用相同的实体实例,它们具有相同的“id” ,我不确定这是否是错误,但这是问题所在。
标签: java for-loop playframework ebean