【问题标题】:how to merge two collections by updating a value on duplicates如何通过更新重复值来合并两个集合
【发布时间】:2018-04-27 15:31:19
【问题描述】:

我有这门课:

class A{
 int count=0;


 //equals and hashCode implemented
}

创建两个集合:

Collection<A>  collection1;//something
Collection<A>  collection2;//something

连接集合:

Stream.concat(collection1.stream(), collection2.stream())
                //do something here???
                .distinct()
                .sorted(new Comparator<A>() {
                  @Override
                  public int compare(A o1, A o2) {

                     return new Integer(o1.count).compareTo(new Integer(o2.count));
                  }
                })
                .collect(Collectors.toList());

我想合并这两个列表,如果有重复,我想更新整数count; 上面的代码完全摆脱了重复

例如, 假设我们在 collection1 和 collection2 中都有一个对象,它们相等 (o1.equals(o2) == true) 。一个有count=10,另一个有count=20 我想拥有一组不同的对象,该对象有count=30

有办法吗?

【问题讨论】:

  • 我不知道如何更清楚地解释它,你能给我一个建议,以便我可以编辑问题,thx
  • 您是否在比较计数并在匹配时增加计数?我想也许除了计数之外你还需要一些东西来区分你的类。
  • @BillK 说我们得到了 dups,一个 count=10,一个 count=20。我想保留一个count=30!希望这是有道理的伴侣
  • 问题是,你如何识别“那个对象”?看起来你正在通过计数来识别你的对象——我通过你的比较定义来直觉,所以 count=10 和 count=20 的两个将不匹配,并且它们不会被添加到 30,对吧?

标签: java collections java-8


【解决方案1】:

你不能用你当前的方法做到这一点,你可以使用toMap收集器:

Stream.concat(collection1.stream(), collection2.stream())
       .collect(Collectors.toMap(Function.identity(),Function.identity(),
       (left, right) -> {
          left.setCount(left.getCount() + right.getCount());
          return left;
       })).values()
         .stream()
         .sorted(Comparator.comparingInt(A::getCount))
         .collect(Collectors.toList());

这使用Stream.concatcollection1collection2 合并为一个Stream&lt;A&gt;

然后我们调用toMap 收集器,其中第一个Function.identity() 选择源的元素作为键,即A,第二个Function.identity() 也选择源的元素作为值;再次A,所以此时,您可以将数据可视化为Map&lt;A, A&gt;

函数(left, right) -&gt; { ... }被称为合并函数,如果两个给定的对象相等,我们就说取第一个元素的计数并取第二个元素的计数,将它们加在一起并赋值新值返回到我们要保留的元素之一,然后丢弃另一个。

因为您已经覆盖了equalshashcode,所以我们不需要显式调用它,而是会隐式调用equals 方法 确定两个给定对象是否相等。

一旦我们将元素收集到Map&lt;A, A&gt;,然后我们调用values() 方法来检索Collection&lt;A&gt;,这使我们能够使用stream() 方法从它创建一个流,并进一步启用我们使用 sorted 方法对流元素进行排序,最后使用toList 收集器将其收集到List&lt;A&gt;

【讨论】:

  • 伙计,我回家后会试试这个,然后告诉你,你
  • +1 好方法。值得一提的是,如果您不想要一些令人困惑的结果,则需要覆盖 hashCode()equals() 方法才能使这种方法发挥作用。
  • @arthur 完全同意 :)。 OP已经提到实现了equals和hashCode。这在A 类中作为评论提到。
  • @Aominè 它工作得很好,伙计,你能解释一下这段代码是如何工作的吗,我就是想不通!
  • @Aominè 例如equals()hashCode() 如何/在哪里使用?
猜你喜欢
  • 2011-08-30
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-25
相关资源
最近更新 更多