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.