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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 18:54:49  来源:igfitidea点击:

Find objects in a list where some attributes have equal values

java

提问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?

相关问题:如何最好地比较 Java 中的两个集合并对其采取行动?