You were almost correct with groupingBy, but the second parameter of that is a Collector, not a Function. Thus I used toMap.
Map<String, Integer> map = Stream.of("bla", "blabla", "blablabla").distinct()
.collect(Collectors.toMap(Function.identity(), String::length));
Answer from Eugene on Stack OverflowYou were almost correct with groupingBy, but the second parameter of that is a Collector, not a Function. Thus I used toMap.
Map<String, Integer> map = Stream.of("bla", "blabla", "blablabla").distinct()
.collect(Collectors.toMap(Function.identity(), String::length));
You don't have to do something so complicated. Here is an example code:
...
...
List<String> ll= // the list of words that you have.
Map<String,Integer> map = new HashMap<>();// or any other kind of map you want to create
for(String s:ll){
map.put(s,s.length());
}
Now you have a map that satisfies your requirement.
Converting string to Map<Integer,String> in java 8 - Stack Overflow
java - List of String to Map Java8 - Stack Overflow
Java 8 streams - String to HashMap counter of characters
Convert String array to Map using Java 8 Lambda expressions - Stack Overflow
Split the string by , to get individual map entries. Then split them by = to get the key and the value.
Map<String, String> reconstructedUtilMap = Arrays.stream(utilMapString.split(","))
.map(s -> s.split("="))
.collect(Collectors.toMap(s -> s[0], s -> s[1]));
Note: As pointed out by Andreas@ in the comments, this is not a reliable way to convert between a map and a string
EDIT: Thanks to Holger for this suggestion.
Use s.split("=", 2) to ensure that the array is never larger than two elements. This will be useful to not lose the contents (when the value has =)
Example: when the input string is "a=1,b=2,c=3=44=5555"
you will get {a=1, b=2, c=3=44=5555}
Earlier (just using s.split("=")) will give
{a=1, b=2, c=3}
Here is another option which streams a list of 1=1 etc. terms into a map.
String input = "1=1,2=2,3=3,4=4,5=5";
Map<String, String> map = Arrays.asList(input.split(",")).stream().collect(
Collectors.toMap(x -> x.replaceAll("=\\d+$", ""),
x -> x.replaceAll("^\\d+=", "")));
System.out.println(Collections.singletonList(map));
[{1=1, 2=2, 3=3, 4=4, 5=5}]
You can use IntStream to get this thing done. Use the integer value as the key, and the relevant value in the string array at that index as the value of the map.
Map<Integer, String> counterToStr = IntStream.range(0, strings.length)
.boxed()
.collect(Collectors.toMap(Function.identity(), i -> strings[i]));
Another alternative that obviates the need of split would be,
Map<Integer, String> counterToStr = IntStream.range(0, strings.length)
.boxed()
.collect(Collectors.toMap(Function.identity(), i -> str.charAt(i) + ""));
You can write like
String str = "abcd";
Map<Integer, Character> map = IntStream.range(0, str.length()).boxed()
.collect(Collectors.toMap(Function.identity(), pos -> str.charAt(pos)));
No need to split the String with String[] strings = str.split(""); A simple one-liner.
Given a String, I want to create a hashmap that maps a Character to the number of times it shows up in the string.
I saw in Stack Overflow the following line:
Map<String, Long> map =
Arrays.stream(s1.split("")).
collect(Collectors.groupingBy(c -> c, Collectors.counting()));
And it works great, but it maps a String to the counter.
I tried writing it for Characters, and as far as I understood, there isn't a char stream, and I'll have to use IntStream. So I converted it to an IntStream, and used the same Collectors function.
Map<Integer, Long> map =
s1.chars().
collect(Collectors.groupingBy(c -> c, Collectors.counting()));
The above doesn't work. The error is:
Error:(14, 27) java: method collect in interface java.util.stream.IntStream cannot be applied to given types;
required: java.util.function.Supplier<R>,java.util.function.ObjIntConsumer<R>,java.util.function.BiConsumer<R,R>
found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.Map<java.lang.Object,java.lang.Long>>
reason: cannot infer type-variable(s) R
(actual and formal argument lists differ in length)
What is the difference between the two?
You can use the following snippet for this:
Map<String, Map<String, String>> result = Arrays.stream(samp.split(","))
.map(i -> i.split("-"))
.collect(Collectors.groupingBy(a -> a[0], Collectors.toMap(a -> a[1], a -> a[2])));
First it creates a Stream of your items, which are mapped to a stream of arrays, containing the subitems. At the end you collect all by using group by on the first subitem and create an inner map with the second value as key and the last one as value.
The result is:
{101={1=5, 2=4}, 102={1=5, 2=5, 3=5}, 103={1=4}}
Map<String, Map<String, String>> map = Arrays.stream(samp.split(","))
.map(s -> s.split("-"))
.collect(Collectors.toMap(
o -> o[0],
o -> Map.of(o[1], o[2]),
(m1, m2) -> Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));
Map.of is from Java 9, you can use AbstractMap.SimpleEntry if you are on Java 8.
Samuel's answer is better though, much concise.
Since you want to return the result map of the first Result element to pass your filter, you can obtain it with findFirst():
Optional<Map<String,Integer>> resultMap =
resultList.stream()
.filter(result->"xxx".equals(result.getName()))
.map(Result::getResultMap)
.findFirst();
You can extract the Map from the Optional this way:
Map<String,Integer> resultMap =
resultList.stream()
.filter(result->"xxx".equals(result.getName()))
.map(Result::getResultMap)
.findFirst()
.orElse(null);
if you're only looking for one item:
resultList.stream()
.filter(result -> "xxx".equals(result.getName()))
.map(Result::getResultMap)
.findAny();
if the filter could match more than one item then you'll need to flatten then toMap it:
resultList.stream()
.filter(result-> "xxx".equals(result.getName()))
.flatMap(result -> result.getResultMap().entrySet().stream())
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
if there can be duplicates then use the merge function to resolve collisions:
resultList.stream()
.filter(result -> "xxx".equals(result.getName()))
.flatMap(result -> result.getResultMap().entrySet().stream())
.collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (l, r) -> l));