Java - 如何从集合中删除具有相同属性值的元素?

时间:2015-01-26 08:04:28

标签: java algorithm list collections

假设有SomeField属性的SomeClass元素的集合。如何从此Collection中删除具有等效SomeField属性的重复元素,并仅保留一个具有该SomeField值的元素?

5 个答案:

答案 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已明确定义equalshashCode),然后取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中的SomeClassSomeField然后只需将原始集合添加到HashSet

如果不是这种情况且SomeClass更复杂,您仍然可以使用Set。但是,您需要以某种方式过滤掉重复项,并且一种好方法是使用ComparatorTreeSet

// 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());
    }
}