简体   繁体   中英

Java: Merging two lists from complex objects with duplicates to one ordered list

First off my problem is similiar to this already answered question Merging two arrayLists into a new arrayList, with no duplicates and in order, in Java .

However the difference here is that I tried to merge two lists with more than just a String together. The intention on my side was to merge two objects of the following kind (to simplify things I striped unnecessary infos from the example):

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

So that I get a new oject which has a summarized count out. This will eliminate unwanted duplicates because the uniqueKey on these objects was identical. The reason for this is that I mapped several business types to only one technical type.

The problem here is that you have to account for every possiblity in order to handle the merge correctly and don't miss an original object.

Here are some cases I tried to cover with unit test:

  • One normal, followed by two duplicates, and one normal = normal, merged, normal
  • Two duplicates, followed by two normal = merged, normal, normal
  • Two normal, followed by two duplicates = normal, normal, merged

and so on and so forth...

So how to solve that without going crazy?

Since I spent half a day with that problem, I thought the simple answer might be useful to someone else.

So what did I try:

  1. I decided not to go recursive since I avoid it if I can for obvious reasons and used two nested loops
  2. I wrote unit tests for every case I could think of
  3. Then I tried step by step to make them all green
  4. I banged my head against the table because everytime I made one green another one went red
  5. I asked a colleague
  6. He let me state the problem without showing him my "solution"

Here's the magic 15 min solution:

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM