【问题标题】:How to find common entries in a list, based off of one variable in the object?如何根据对象中的一个变量在列表中查找常见条目?
【发布时间】:2017-10-17 17:20:11
【问题描述】:

我有课

public class A{
   private String x;
   private String y;
   private String z;
}

我有多个列表List<List<A>>,需要在所有列表中找到共同的条目。如果一个对象的 x == 另一个对象的 x,则条目相同。

如果我正在检查对象的相等性,我可以将列表转换为集合并使用retainAll()。但是当 y 和 z 可能不同时,我该怎么做呢? x 必须相同。

【问题讨论】:

  • 不确定我是否正确,但似乎您只需要为您的 A 类覆盖 equals 和哈希码,因此仅当 this.x == x 时它才返回 true
  • 构造一个Map<String, List<A>>。遍历列表列表中的所有As,并将每个添加到与A 的成员x 关联的Map 值。完成后,您的地图将为所有 A 中的每个不同的 x 提供一个条目,并且该条目的值将包含所有 Ax 的列表.
  • 如果你真的想根据对象标识 (==) 而不是相等 (equals()) 进行匹配,那么选择 IdentityHashMap 作为地图实现。
  • 您期望的输出是什么? List 是否具有对象 A.x 相同的值?

标签: java list set


【解决方案1】:

这个问题是 Java8 流的一个很好的用例,您可以在其中应用不同的收集器来累积流的元素。下面的代码将执行请求的转换:

Map<String, List<A>> collect = lists.stream()
        .flatMap(Collection::stream)
        .collect(Collectors.groupingBy(A::getX));

这个 API 确实提高了可读性,但也可能提供良好的性能,因为这个 Collector 是由 JDK 提供的。

您可以在这里找到一个工作示例:https://gist.github.com/sermojohn/e8828288172d5c9e85046c4b25a7d425

【讨论】:

    【解决方案2】:

    在你的课堂上,编写一个函数来返回你的 X 值....

    public class A {
        private String x;
        private String y;
        private String z;
        ...
        public String getX() {
            return x;
        }
    }
    

    ...然后遍历列表列表 (O(n^2)) 并根据它们的共同 X 值对它们进行排序。

    public Map<String, List<A>> findCommonEntries(List<List<A>> aListList) {
        Map<String, List<A>> aMap = new HashMap<>();
    
        for (List<A> aList : aListList) {
            for (A a : aList) {
                if (!aMap.containsKey(a.getX()))
                    aMap.put(a.getX(), new ArrayList<>());
    
                aMap.get(a.getX()).add(a);
            }
        }
    }
    

    最后,您应该将存储在 X 中任何位置的所有字符串映射到包含该 X 的所有 A 的列表。

    【讨论】:

      【解决方案3】:

      您可以将所有列表平铺成一个列表,使用 x 字段对所有元素进行分组,然后保留所有列表中存在的键(按值大小):

      public static Set<String> getCommonEntries(List<List<A>> lists) {
          Map<String, List<A>> map = lists.stream()
                                          .flatMap(Collection::stream)
                                          .collect(Collectors.groupingBy(A::getX));
          map.values().removeIf(l -> l.size() != lists.size());
          return map.keySet();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-02
        • 1970-01-01
        • 1970-01-01
        • 2017-05-17
        • 2010-09-17
        • 2017-06-07
        • 1970-01-01
        相关资源
        最近更新 更多