java 在列表中查找某些属性具有相等值的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2012551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Find objects in a list where some attributes have equal values
提问by Thomas L?tzer
Given a list of objects (all of the same type), how can I make sure that it contains only one element for each value of a certain attribute, even though equals() may return false for such elements due to more attributes being checked? In code:
给定一个对象列表(所有类型都相同),我如何确保它只包含某个属性的每个值的一个元素,即使由于检查了更多属性,equals() 可能会为此类元素返回 false?在代码中:
private void example() {
List<SomeType> listWithDuplicates = new ArrayList<SomeType>();
/*
* create the "duplicate" objects. Note that both attributes passed to
* the constructor are used in equals(), though for the purpose of this
* question they are considered equal if the first argument was equal
*/
SomeType someObject1 = new SomeObject1("hello", "1");
SomeType someObject2 = new SomeObject1("hello", "2");
List<SomeType> listWithoutDuplicates = removeDuplicates(listWithDuplicates)
//listWithoutDuplicates should not contain someObject2
}
private List<SomeType> removeDuplicates(List<SomeType> listWithDuplicates) {
/*
* remove all but the first entry in the list where the first constructor-
* arg was the same
*/
}
回答by Anurag
Could use a Set as an intermediary placeholder to find the duplicates as Bozho suggested. Here's a sample removeDuplicates()implementation.
可以使用 Set 作为中间占位符来查找 Bozho 建议的重复项。这是一个示例removeDuplicates()实现。
private List<SomeType> removeDuplicates(List<SomeType> listWithDuplicates) {
/* Set of all attributes seen so far */
Set<AttributeType> attributes = new HashSet<AttributeType>();
/* All confirmed duplicates go in here */
List duplicates = new ArrayList<SomeType>();
for(SomeType x : listWithDuplicates) {
if(attributes.contains(x.firstAttribute())) {
duplicates.add(x);
}
attributes.add(x.firstAttribute());
}
/* Clean list without any dups */
return listWithDuplicates.removeAll(duplicates);
}
回答by Vincent Ramdhanie
Maybe a HashMap can be used like this:
也许 HashMap 可以这样使用:
private List<SomeType> removeDuplicates(List<SomeType> listWithDuplicates) {
/*
* remove all but the first entry in the list where the first constructor-
* arg was the same
*/
Iterator<SomeType> iter = listWithDuplicates.iterator();
Map<String, SomeType> map = new HashMap<String, SomeType>();
while(iter.hasnext()){
SomeType i = iter.next();
if(!map.containsKey(i.getAttribute())){
map.put(i.getAttribute(), i);
}
}
//At this point the map.values() is a collection of objects that are not duplicates.
}
回答by Carl Smotricz
If equals()were suitable, I could recommend some "standard" Collections classes/methods. As it is, I think your only option will be to either
如果equals()合适,我可以推荐一些“标准”集合类/方法。事实上,我认为你唯一的选择是要么
copy each element to another list after first checking all precedingelements in the original list for duplicates; or
delete from your list any element for which you've found a duplicate at a preceding location. For in-list deletion, you'd be best off with using a
LinkedList, where deletion isn't so expensive.
在首先检查原始列表中所有前面的元素是否重复后,将每个元素复制到另一个列表;或者
从您的列表中删除您在先前位置发现重复项的任何元素。对于列表内删除,最好使用 a
LinkedList,其中删除不是那么昂贵。
In either case, checking for duplicates will be an O(n^2) operation, alas.
在任何一种情况下,检查重复项都是 O(n^2) 操作,唉。
If you're going to be a lot of this kind of operation, it might be worthwhile to wrap your list elements inside another class that returns a hashcode based on your own defined criteria.
如果您要进行大量此类操作,可能值得将列表元素包装在另一个类中,该类根据您自己定义的标准返回哈希码。
回答by Ben
I'd look at implementing the Comparatorinterface for something like this. If there's a simple attribute or two that you wish to use for your comparison, that makes it pretty straightforward.
我会考虑Comparator为这样的东西实现接口。如果您希望使用一两个简单的属性进行比较,这将非常简单。
Related question: How Best to Compare Two Collections in Java and Act on Them?

