JAVA process two stream into one single map [duplicate] - java

This question already has answers here:
Zip two lists into an immutable multimap in Java 8 with Guava?
(3 answers)
Closed 2 years ago.
I have two streams
Stream<Key> keys;
Stream<Value> values;
I want combine them into a single Map
Map<Key, Value> result = someMagicMethod(keys, values);
Is there any elegant way to do that?
I know there is a method called Stream.concat, but it's not for this case.

Guava Streams.zip for streams without random access
If Guava is available at runtime, then the following can help:
List<String> keys = Arrays.asList("One", "Two");
List<Integer> values = Arrays.asList(1, 2);
Map<String, Integer> zipped = Streams.zip(keys.stream(), values.stream(), SimpleEntry::new)
.collect(Collectors.toMap(Collectors.toMap(Entry::getKey, Entry::getValue)));
System.out.println(zipped);

You can first collect both streams to a List.
List<Key> keyList = keys.collect(Collectors.toList());
List<Value> valueList = values.collect(Collectors.toList());
Map<Key, Value> map = IntStream.range(0, keyList.size())
.boxed().collect(Collectors.toMap(keyList::get, valueList::get));
System.out.println(map);

Related

How to get map from list of object using stream? [duplicate]

This question already has answers here:
Java 8 List<V> into Map<K, V>
(23 answers)
Closed 2 years ago.
I have class country:
class Country {
private String code;
private String name;
}
I need to do from list of Countries to Map with code and name.
I tried to
Map<String, String> countryNames = countries.stream()
.collect(Collectors.groupingBy(Country::getCode, Country::getName));
But it is not right. How to collect correct?
I assume you want code as the key and name as the value. In that case, you need to use Collectors.mapping as the downstream collector to Collectors.groupingBy. Like this:
Map<String, List<String>> countryNames = countries.stream()
.collect(Collectors.groupingBy(Country::getCode,
Collectors.mapping(Country::getName, Collectors.toList())));
Note that this will return the values as a list of strings, as the names are grouped in a list (by Collectors.toList()) if there are multiple countries with the same code.
If you know that each code only appears once in the list, you can use Collectors.toMap instead.
Map<String, String> countryNames = countries.stream()
.collect(Collectors.toMap(Country::getCode, Country::getName));

sort hashmap value of type list using java 8 [duplicate]

This question already has answers here:
How to sort a List/ArrayList?
(21 answers)
Closed 2 years ago.
I have a map of String key and Value is List of Strings, I want the List inside the map to be sorted alphabetically, how to do that using java 8
K1=[ "Tomato", "potato","Apple"],
K2=["Plan", "car", "train"]
result should be
K1=[ "Apple" , "potato","Tomato"],
K2=["car","Plan", "train"]
Try below function
static void sort(Map<String, List<String>> stringListHashMap) {
stringListHashMap.forEach((key, value) -> {
Collections.sort(value);
});
}
While inserting into Map, sort your list or after retrieve sort your list.
Refer below code for your reference:
Map<String, List<String>> data= new HashMap<>();
List<String> list1= Stream.of("AAA","CCC","BBB","DDD").sorted().collect(Collectors.toList());
List<String> list2= Stream.of("CCC","DDD","BBB","AAA").sorted().collect(Collectors.toList());
data.put("A",list1.stream().sorted().collect(Collectors.toList()));
data.put("B", list2);
System.out.println(data);
Hope this will help you.
Map<String, List<String>> yourMap= new HashMap<>();
List list1 = Arrays.asList("Tomato", "potato","Apple");
List list2 = Arrays.asList("Plan", "car", "train");
data.put("A",list1.sorted().collect(Collectors.toList()));
data.put("B", list2.sorted().collect(Collectors.toList()));
This will give you what you are looking for.
Use TreeSet as map's value element which keeps values already sorted based on comparator provided.
Comparator<? super String> comparator = String::compareToIgnoreCase;
Map<String, TreeSet<String>> map = new HashMap<>();
TreeSet<String> K1_values = new TreeSet<>(comparator);
K1_values.add("Tomato");
K1_values.add("potato");
K1_values.add("Apple");
map.put("K1", K1_values);
TreeSet<String> K2_values = new TreeSet<>(comparator);
K2_values.add("Plan");
K2_values.add("car");
K2_values.add("train");
map.put("K2", K2_values);
System.out.println(map);
It prints:
{K1=[Apple, potato, Tomato], K2=[car, Plan, train]}
The items in sorted order as you need.
Hope this helps!

How to add values from Map<T,List<L>> map to List<L>? [duplicate]

This question already has answers here:
Convert List of List into list in java
(5 answers)
Closed 5 years ago.
I have a multimap Map<T,List<L>> map and I need a list with all the values of the values from the map, namely List<L>. With map.values() I get a List<List<L>>, but thats not what I want.
Does someone know a clean solution without looping?
If you are using Java 8, you could collect all L values from all List<L>s in a single List<L> by Stream#flatMap:
final List<L> list = map
// get a Collection<List<L>>
.values()
// make a stream from the collection
.stream()
// turn each List<L> into a Stream<L> and merge these streams
.flatMap(List::stream)
// accumulate the result into a List
.collect(Collectors.toList());
Otherwise, a for-each approach with Collection#addAll can be applied:
final List<L> list = new ArrayList<>();
for (final List<L> values : map.values()) {
list.addAll(values);
}

Keeping order on hash map keys during collecting them [duplicate]

This question already has answers here:
How do I keep the iteration order of a List when using Collections.toMap() on a stream?
(6 answers)
Closed 5 years ago.
I have the following hash map
Map<String,Double> map_1 = new LinkedHashMap<>();
with some keys: e.g. ["hello_1", "hello_2", "hello_3"].
Then, I iterate through these keys using stream API and saving new results in map2:
Map<String,Double> map_2 = new LinkedHashMap<>();
map_2 = map_1.keySet()
.stream()
.collect(
Collectors.toMap(entry -> entry,
entry -> {
Double value = map_1.get(entry);
return (value + 5);
}));
but the new hash map has keys in another order, despite it is defined as LinkedHashMap. I think the problem is during stream + collect steps.
Anyone could suggest me a solution?
Thanks
The order of the keys actually gets messed up in the collect step in this case.
You need to specify that you want to collect to a LinkedHashMap.

Java - How to create hashmap which holds muliple values for a singe key? [duplicate]

This question already has answers here:
HashMap with multiple values under the same key
(21 answers)
Closed 7 years ago.
I want to implement Hash table with multiple values in java i.e
// if sample is a hashmap
sample.put(1,1);
sample.put(1,2);
and sample.get(1); will return 2 values.
How can i achieve this?
You can use a Multimap instead. It keeps multiple values for a key in a list. There are implementations in commons-collections and in Guava.
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("ducks", "Huey");
multimap.put("ducks", "Dewey");
multimap.put("ducks", "Louie");
Collection<String> ducks = multimap.get("ducks");
System.out.println(ducks); // [Huey, Dewey, Louie]
It is similar to using a Hashmap where the values are lists, but you don't have to explicitly create the lists.
The same example done the do-it-yourself way looks like:
Map<String, List<String>> map = new HashMap<>();
map.put("ducks", new ArrayList<String>());
map.get("ducks").add("Huey");
map.get("ducks").add("Dewey");
map.get("ducks").add("Louie");
// or as an alternative to the prev 4 lines:
// map.put("ducks", new ArrayList<String>(
// new String[] {"Huey", "Dewey", "Louie"}));
Collection<String> ducks = map.get("ducks");
System.out.println(ducks); // [Huey, Dewey, Louie]
Note that you can use the Multimap as a builder and call asMap on it to return a map.
Try HashMap<Key, List<Value>> You will need to manage the list, creating if it doesn't exist already, and adding to it if you need.
Guava also provides a Multimap implementation
Do it this way
Map<String, List> map = new HashMap<String, List>();
List listOne = new ArrayList();
for(int i=0;i<4;i++){
listOne.add(i);
}
List listTwo = new ArrayList();
for(int i=4;i<6;i++){
listTwo.add(i);
}
map.put("listOne",listOne);
map.put("listTwo",listTwo);
Or you can even use Guava's Multimap

Categories