Reputation: 5235
I have a map like below:
Map<String, String> map1 = new HashMap<String, String>();
and the contents are:
ID_1 -> ID_2
------------
100 -> 10
200 -> 20
300 -> 30
Based on the value of ID_2 I have to query an oracle table and get a code value corresponding to each entry:
ID_1 -> ID_2 -> code
--------------------
100 -> 10 -> 8
200 -> 20 -> 2
300 -> 30 -> 9
and then I will have to get the map1 sorted in ascending way by the code value i.e the result should be:
200 -> 20
100 -> 10
300 -> 30
I have thought of creating an intermediary map with <ID_1, List<ID_2,code>>
as <K,V>
and then sort using the code value and then get the final output.
Is there any shorter way to do so, like without using an intermediary map?
Upvotes: 0
Views: 86
Reputation: 12817
With Java streams you can achieve this without using any additional collections, here is an implementation.
To maintain order have used LinkedHashMap
in the collector
For simplicity I have taken one more map to hold the db values [you need to change this to get from DB]
Map<String, String> map1 = new HashMap<String, String>();
map1.put("100", "10");
map1.put("200", "20");
map1.put("300", "30");
Map<String, String> dbmap = new HashMap<String, String>();
dbmap.put("10", "8");
dbmap.put("20", "2");
dbmap.put("30", "9");
Comparator<String> comp = (k1, k2) -> dbmap.get(map1.get(k1)).compareTo(dbmap.get(map1.get(k2)));
Map<String, String> queryMap = map1.keySet().stream().sorted(comp)
.collect(toMap((String key) -> key, value -> (String) map1.get(value), (u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
}, LinkedHashMap::new));
System.out.println(queryMap);
Ouput
{200=20, 100=10, 300=30}
Upvotes: 0
Reputation: 9308
I would express you logic as follow :
It is important to notice that few maps have ordering constraints. The base implementation that comes to mind is LinkedHashMap. Furthermore "reordering an existing map" seems like a strange idea that is not backed by any methods in the Map
interface. So in a nutshell, saying you need to return a Map
that has an ordering constraint seems like a bad/incomplete idea - but it is certainly doable.
I would also adivse against using a TreeMap
which is a Map ordered by a Comparator
because I see no constraint that your ordering values are unique. Plus, your ordering is on the values, not the keys, of the map. Such a comparator would not be straightforward at all.
So, in short, what I would do is
LinkedHashMap<String, String> sorted = map.entrySet().stream()
// This is your DB call
.sorted(Comparator.comparing(entry -> getDBValue(entry)))
// Now we have an ordered stream of key/value entries from the original map
.collect(
// We flush back to a Map
Collectors.toMap(
// Keeping the original keys as is
Map.Entry::getKey,
// Keeping the original values as is
Map.Entry::getValue,
// This merge step should never be called, as keys are unique. Maybe you could assert that and fail if this is called
(v1, v2) -> v1,
// This is where you instanciate the Map that respects ordering of keys. Here, LinkedHashMap is iterable in the order of insertion, which is what we want.
LinkedHashMap::new
)
);
Upvotes: 0
Reputation: 6079
You try this code below: I used int[]
array instead of List
public class Test {
public static void main(String[] args) throws Exception {
Map<String, int[]> map = new HashMap<>();
map.put("100", new int[]{10, 8});
map.put("200", new int[]{20, 2});
map.put("300", new int[]{30, 9});
Map<String, int[]> sortByValue = sortByValue(map);
for (Map.Entry<String, int[]> entry : sortByValue.entrySet()) {
System.out.println(entry.getKey() +" -> "+ entry.getValue()[0]);
}
}
private static Map<String, int[]> sortByValue( Map<String, int[]> map ) {
List<Map.Entry<String, int[]>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, (o1, o2) -> Integer.compare(o1.getValue()[1], o2.getValue()[1]));
Map<String, int[]> result = new LinkedHashMap<>();
for (Map.Entry<String, int[]> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
}
And it is the result:
200 -> 20
100 -> 10
300 -> 30
Upvotes: 1
Reputation: 4532
Based on map1 you can build new map:
Map<String, Pair<String, String> map2
where key is id from oracle db.
As you need to have ordering you can use TreeMap and method
Map.Entry<K,V> firstEntry();
Upvotes: 0