-1

I have a arraylist which contains these values:

ArrayList<string,string> list= new ArrayList<>();
list.put("A101","2020_1.0");
list.put("A101","2020_3.0");
list.put("A101","2020_2.0");
list.put("A102","2020_2.0");
list.put("A102","2020_1.0");

I need to get: A101 2020_3.0 and A102 2020_2.0

1 Answers1

0

First, the data container here does not appear to be a List<String>, it is rather a Map<String, String> because List does not have method put(K key, V value); while Map does.

However, if method Map::put is used, it overwrites previous values with the new ones. So, a custom map may be implemented with the overridden method put (as well as putAll) to compare the values and keep the one with the "highest" version.

class MyMap<K, V> extends LinkedHashMap<K, V> {

    private final Comparator<V> valueComparator;

    public MyMap(Comparator<V> valueComparator) {
        super();
        this.valueComparator = valueComparator;
    }

    @Override
    public V put(K key, V value) {
        return compute(key, 
            (k, v) -> v == null ? value // value missing
                                : valueComparator.compare(v, value) < 0 
                                ? value : v // keep the max of two
        );
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {
        m.forEach(this::put);
    }
}

Assuming that in the existing examples the values can be compared as usual Strings, the map may be created as follows:

// use plain String comparison
Map<String, String> data = new MyMap<>(String::compareTo);

data.put("A101", "2020_1.0");
data.put("A101", "2020_3.0");
data.put("A101", "2020_2.0");
data.put("A102", "2020_2.0");
data.put("A102", "2020_1.0");

System.out.println(data);

Output:

{A101=2020_3.0, A102=2020_2.0}

If the "version" values have more complex comparison rules (e.g. split to integer parts as in 9.1 and 10.0, exclude some prefix/suffix, etc.), a custom comparator needs to be implemented.

Nowhere Man
  • 19,170
  • 9
  • 17
  • 42