Java:将具有重复项的复杂对象中的两个列表合并到一个有序列表中

时间:2015-11-08 18:26:50

标签: java algorithm list merge duplicates

首先,我的问题类似于已经回答的问题Merging two arrayLists into a new arrayList, with no duplicates and in order, in Java

然而,这里的不同之处在于我尝试将两个列表合并而不仅仅是一个String。我的意图是合并两个以下类型的对象(为了简化我从示例中划分不必要的信息的事情):

public class Data{
  private int count;
  private Type type;
  private Key uniqueKey;
}

这样我就得到了一个新的对象,它有一个汇总计数。这将消除不需要的重复,因为这些对象上的uniqueKey是相同的。原因是我将几种业务类型映射到一种技术类型。

这里的问题是你必须考虑到所有可能性才能正确处理合并并且不要错过原始对象。

以下是我试图用单元测试覆盖的一些案例:

  • 一个正常,然后是两个重复,一个正常=正常,合并,正常
  • 两个重复,然后是两个正常=合并,正常,正常
  • 两个正常,然后是两个重复=正常,正常,合并

依旧等等......

那么如何解决这个问题而不会发疯?

1 个答案:

答案 0 :(得分:1)

由于我花了半天时间处理这个问题,我认为这个简单的答案可能对其他人有用。

那我尝试了什么:

  1. 我决定不去递归,因为我可以避免它,如果我可以出于明显的原因并使用两个嵌套循环
  2. 我为每个我能想到的案例编写单元测试
  3. 然后我一步一步地试图让它们全为绿色
  4. 我把头撞在桌子上,因为每当我做一个绿色的时候,另一个人就变红了
  5. 我问了一位同事
  6. 他让我在没有向他展示我的“解决方案”的情况下陈述问题
  7. 这是神奇的15分钟解决方案:

    public static LinkedList<Data> merge(final LinkedList<Data> source) {
        final HashMap<Data, Integer> temp = new HashMap<>();
    
        for (final Data data : source) {
            final int count = data.getCount();
            data.setCount(0);
            if (temp.get(data) == null) {
                temp.put(data, count);
            }
            else {
                temp.put(data, temp.get(data) + count);
            }
        }
    
        final Set<Entry<Data, Integer>> set = temp.entrySet();
        final LinkedList<Data> result = new LinkedList<>();
    
        for (final Entry<Data, Integer> entry : set) {
            final Data mergedData = entry.getKey();
            mergedData.setCount(entry.getValue());
            result.add(mergedData);
        }
    
        Collections.sort(result, new DataComparator());
    
        return result;
    }