Java 删除重复的ArrayList自定义对象
我有一个ArrayList,它包含类Java 删除重复的ArrayList自定义对象,java,arraylist,duplicate-removal,Java,Arraylist,Duplicate Removal,我有一个ArrayList,它包含类事件的元素。 事件有两个属性,Name和Timestamp。 该列表现在显示所有事件。 我想删除具有相同名称但时间戳不同的重复项,并将它们放在另一个列表中。这样,用户可以单击具有该名称的事件,然后选择日期 我已经在为我的应用程序中的一些其他功能重写函数equals(比较名称和时间戳) 如何解决此问题?如果您已经有自己的equals方法,则不能使用哈希集合。您必须通过执行嵌套循环来手动检查它: List<Event> allEvents = // f
事件的元素。
事件有两个属性,Name
和Timestamp
。
该列表现在显示所有事件。
我想删除具有相同名称但时间戳不同的重复项,并将它们放在另一个列表中。这样,用户可以单击具有该名称的事件,然后选择日期
我已经在为我的应用程序中的一些其他功能重写函数equals(比较名称和时间戳)
如何解决此问题?如果您已经有自己的equals方法,则不能使用哈希
集合。您必须通过执行嵌套循环来手动检查它:
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);
}
List allEvents=//用事件填充。
List noRepeat=new ArrayList();
对于(事件:allEvents){
布尔值isFound=false;
//检查noRepeat中是否存在事件名称
对于(事件e:noRepeat){
如果(e.getName().equals(event.getName())| |(e.equals(event))){
isFound=true;
打破
}
}
如果(!isFound)noRepeat.add(事件);
}
您应该重写事件类中的equals()
和hashCode()
方法,并将所有对象添加到集中,而不是列表中。如果您正确地重写了equals()
和hashCode()
,集合
将不允许重复对象,我认为您使用了错误的数据结构。您希望使用映射
和字符串
(名称)映射到设置
(唯一事件)的实现
下面是我们测试它的方法:
创建一些事件
创建Map您是否尝试过使用HashSet而不是ArrayList?是否有类似于相同名称和相同时间戳的情况,并希望将其保存在列表中?您必须保留哪些事件?首次发现?请点击此链接。这显示了列表的备选方案。如果可能的话,你可以走这条路。以其他方式注释为什么标记为重复?重复链接并没有回答这个问题,只是其中的一小部分,它在另一部分的基础上做错了。我引用:“我想删除同名但时间戳不同的重复项,并将它们放在另一个列表中。”。这里的过滤似乎甚至不是真正的目标:“这样,用户可以单击具有该名称的事件,然后选择一个日期。”OP不得不将equals用于其他目的。。。请仔细阅读,我不认为这是一个完整的解决方案。我想删除同名但时间戳不同的重复项,并将它们放入另一个列表中。你还需要检查timmestamps是否相等。他有一个equals方法来检查这两个参数,他需要从列表中删除同名事件:OP说:我想删除同名的重复项,但是不同的时间戳是我的方法所做的…是的,但是既然ArrayList
可以包含重复项,那么条件应该是if(e.getName().equals(event.getName()| e.equals(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]
]
}
System.out.println(eventsByName.keySet());
[SecondCategory, FirstCategory]
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);
}