假设有SomeField属性的SomeClass元素的集合。如何从此Collection中删除具有等效SomeField属性的重复元素,并仅保留一个具有该SomeField值的元素?
答案 0 :(得分:1)
Java集合具有可选 remove
方法。假设您正在使用的集合支持它,您可以使用它:
boolean remove(Object o)
从此集合中移除指定元素的单个实例(如果存在)(可选操作)。
假设集合具有add
方法,您可以运行循环从集合中删除元素(使用contains
检查)并且一旦它没有元素{{1它。
add
然后再次 - 从集合中创建while(myCollection.contains(el)){
myCollection.remove(el);
}
myCollection.add(el);
可能更好(例如通过将其传递给Set
构造函数) - 保证集合只包含每个元素的单个实例
TreeSet
答案 1 :(得分:1)
使用Map
。
将所有内容转储到由Map
键入的SomeField
(假设SomeField
已明确定义equals
和hashCode
),然后取Map.values
。< / p>
如果您想保留遇到的最后重复:
final Collection<SomeClass> filtered = list.stream()
.collect(Collectors.toMap(SomeClass::getKey, identity()))
.values();
或者,如果您希望第一个重复反对:
final HashMap<Integer, SomeClass> mapped = list.stream()
.collect(HashMap::new, (m, s) -> m.merge(s.getKey(), s, (l, r) -> l), HashMap::putAll);
final Collection<SomeClass> filtered = mapped.values();
在第二种情况下,类型推断系统需要一些帮助,因此您需要分配中间Map
。
答案 2 :(得分:1)
Collections
课程没有直接remove
方法。您可以实现Collection
接口并实现remove
方法,或使用其他实现之一(LinkedList,Set,ArrayList等);
以下是伪代码,但您可以根据自己的需要进行调整:
Collection<YourType> list = new ArrayList<>();
// Add your objects to it - to make your collection
for (YourType T: ArrayOfYourType)
list.add(T);
// Remove elements from the list
for (YourType T: list)
if T.getSomeProps() == equals(your_val){ // Or equals()
list.remove(T);
}
您也可以使用地图对列出它们,但这可能对您要做的事情有点过分。
答案 3 :(得分:1)
您需要为SomeClass实现hashCode和equals,以便只考虑SomeField。
class SomeClass {
private SomeField field;
public int hashCode() {
return field.hashCode();
}
public boolean equals(Object o) {
if (o instanceof SomeClass == false){
return false
}
SomeClass someClass = (SomeClass)o;
return someClass.field.equals(this.field)
}
}
现在您可以将所有内容放入Set中以删除重复项
Set set = new HashSet(collection);
答案 4 :(得分:0)
有一些简单的方法可以解决这个问题。
如果SomeField
值是SomeClass
的唯一成员,那么您可以根据hashCode
轻松覆盖equals
中的SomeClass
和SomeField
然后只需将原始集合添加到HashSet
。
如果不是这种情况且SomeClass
更复杂,您仍然可以使用Set
。但是,您需要以某种方式过滤掉重复项,并且一种好方法是使用Comparator
和TreeSet
。
// Create a new Set with a specified comparator
final Collection<SomeClass> someClasses =
new TreeSet<>(Comparator.comparing(SomeClass::getSomeField));
// Add all elements from the original collection (duplicates will be removed)
someClasses.addAll(originalColl);
Comparator.comparing
方法会创建Comparator
。如果您不使用Java 8,也可以使用非lambda Comparator
:
Comparator<SomeClass> comparator = new Comparator<SomeClass>() {
@Override
public int compare(final SomeClass o1, final SomeClass o2) {
// Do some kind of compare-operation. If SomeField is
// Comparable you can do it this way:
return o1.getSomeField().compareTo(o2.getSomeField());
}
}