我有一个ArrayList,它包含类Event
的元素。
事件有两个属性Name
和Timestamp
。
该列表现在显示所有事件。
我想删除具有相同名称但不同时间戳的重复项,并将它们放在另一个列表中。这样,用户可以单击具有该名称的事件,然后选择日期。
我已经在我的应用程序中覆盖函数equals(比较名称和时间戳)以及其他一些功能。
我该如何解决这个问题?
答案 0 :(得分:20)
如果您已拥有自己的等号方法,则无法使用Hash
个收藏集。您必须手动检查它是否实现了嵌套循环:
List<Event> allEvents = // fill with your events.
List<Event> noRepeat = new ArrayList<Event>();
for (Event event : allEvents) {
boolean isFound = false;
// check if the event name exists in noRepeat
for (Event e : noRepeat) {
if (e.getName().equals(event.getName()) || (e.equals(event))) {
isFound = true;
break;
}
}
if (!isFound) noRepeat.add(event);
}
答案 1 :(得分:2)
我认为你正在使用错误的数据结构。您希望使用Map
的实现并将String
(名称)映射到Set<Event>
(唯一事件)。
以下是我们测试它的方式:
Map<String, Set<Event>
。这样我们就可以将名称映射到唯一事件。首先,我们创建一个要测试的事件集合:
Collection<Event> events = new ArrayList<Event>() {
/**
*
*/
private static final long serialVersionUID = 1L;
{
add(new Event("FirstCategory", new Timestamp(0)));
add(new Event("FirstCategory", new Timestamp(0)));
add(new Event("FirstCategory", new Timestamp(1)));
add(new Event("SecondCategory", new Timestamp(2)));
}
};
现在我们在名称及其所有相应的唯一事件之间创建映射:
Map<String, Set<Event>> eventsByName = new HashMap<String, Set<Event>>();
现在我们使用每个名称的唯一事件填充映射:
for (Event e : events) {
if (!eventsByName.containsKey(e.getName())) {
// create new set by name
eventsByName.put(e.getName(), new HashSet<Event>());
}
// add event to existing Set.
// duplicates will be dropped since it's a `Set`
eventsByName.get(e.getName()).add(e);
}
检查我们得到了什么:
System.out.println(eventsByName);
输出:
{
SecondCategory=[
Event [name=SecondCategory, timestamp=1970-01-01 02:00:00.002]
],
FirstCategory=[
Event [name=FirstCategory, timestamp=1970-01-01 02:00:00.0],
Event [name=FirstCategory, timestamp=1970-01-01 02:00:00.001]
]
}
提示1:
要获取名称列表,您只需要查看Map
的密钥,这些密钥实际上也是Set
:
System.out.println(eventsByName.keySet());
输出:
[SecondCategory, FirstCategory]
提示2:
如果这不符合您的期望,并且您希望获得不同的唯一性定义,则可以实施Comparator<Event>
并将其与TreeSet<Event>
一起使用,而不是使用HashSet<Event>
}无法接受自定义Comparator
。
所以,如果你有一个班级:
class EventByRandomDefinitionComparator implements Comparator<Event>{
// implementation ...
}
填写映射时需要完成以下任务:
// create different comparison mechanism
Comparator<Event> comparator = new EventByRandomDefinitionComparator();
for (Event e : events) {
if (!eventsByName.containsKey(e.getName())) {
// create new set by name
// changed Set implementation to use new comparator
eventsByName.put(e.getName(), new TreeSet<Event>(comparator)));
}
// add event to existing Set.
// duplicates will be dropped since it's a `Set`
eventsByName.get(e.getName()).add(e);
}
祝你好运。
答案 2 :(得分:-1)
您应该覆盖Event类中的equals()
和hashCode()
方法,并在Set
而不是List
中添加所有对象。如果您已正确覆盖Set
和equals()
,hashCode()
将不允许重复的对象。