I'm studying for Java 8 Lambda and Unary Functional Interface. I have a practice assignment about "Function" class using HashMap
, which the following steps to do:
Create a variable of type Function<Set, Map>
that receives a Set
and creates a HashMap
using lambda expressions
Put words in the map, using as key the uppercase first letter of that word
Execute lambda expression and view the result
I trying in the following way, but it doesn't work. I think that the problem is in the lambda expression, but I want to understand how I have to do (for simplicity I put the same word as key). In this way, the result is "null".
import java.util.*;
import java.util.function.Function;
public class FunctionTest {
public static void main(String[] args) {
HashSet<String> hs = new HashSet<String>();
hs.add("ciao");
hs.add("hello");
hs.add("hallo");
hs.add("bonjour");
Function<Set, Map> setToMap = s2 -> (Map) new HashMap().put(s2,s2);
System.out.println(setToMap.apply(hs));
}
}
For the above example, the expected result should be {B=bonjour, C=ciao, H=hello}
.
I think this means that you have to add all the words
of the Set
in the Map
following 2 rules
Function<Set<String>, Map<Character, String>> setToMap = aSet -> {
Map<Character, String> map = new HashMap<>();
for (String s : aSet ) {
map.put(s.toUpperCase().charAt(0), s);
}
return map;
};
// or using Streams :
Function<Set<String>, Map<Character, String>> setToMap = aSet ->
aSet.stream().collect(Collectors.toMap(s -> s.toUpperCase().charAt(0),
Function.identity(),
(oldK, newK) -> oldK)); // merging function in cas of duplicate key
Tip: don't use raw types, but specify them as much as possible:
Function<Set,Map>
becomes Function<Set<String>, Map<Character, String>>
I bet that you misunderstood your problem a bit.
You probably want a function that gets the key from the value of each item you have in the set. So:
Set<String> set = new HashSet<>();
set.add("ciao");
set.add("hello");
set.add("bonjour");
Function<String, Character> keyExtractor = s -> Character.toUpperCase(s.charAt(0));
Map<Character, String> map = set.stream()
.collect(Collectors.toMap(keyExtractor, Function.identity()));
This assumes you only have one word for each letter.
If you want to have more than one entry for each first letter then you can do:
Set<String> set = new HashSet<>();
set.add("ciao");
set.add("hello");
set.add("hallo");
set.add("bonjour");
Function<String, Character> keyExtractor = s -> Character.toUpperCase(s.charAt(0));
Map<Character, List<String>> map = set.stream()
.collect(Collectors.groupingBy(keyExtractor));
If you wanted to do it without streams, it will be more complicated but possible:
Function<Set<String>, Map<Character, List<String>>> setConverter = set -> {
Map<Character, List<String>> map = new HashMap<>();
for (String s : set) {
Character key = Character.toUpperCase(s.charAt(0));
map.compute(key, (k, v) -> {
if (v == null) {
List<String> newList = new ArrayList<>();
newList.add(s);
return newList;
} else {
v.add(s);
return v;
}
});
}
return map;
};
public class Main {
public static void main(String[] args) {
HashSet<String> hs = new HashSet<String>();
hs.add("ciao");
hs.add("hello");
hs.add("hallo");
hs.add("bonjour");
//System.out.println(setToList.apply(hs));
Function<Set<String>, Map<String,String>> setToMap = s2 -> {
HashMap<String, String> map = new HashMap<>();
for ( String o : s2)
{
map.put(o.toUpperCase(), o);
}
return map;
};
System.out.println(setToMap.apply(hs));
}
public class FunctionTest {
public static void main(String[] args) {
HashSet<String> hs = new HashSet<String>();
hs.add("ciao");
hs.add("hello");
hs.add("hallo");
hs.add("bonjour");
Function<Set<String>,Map> function=set ->{
Map<String,String> mapSet=new HashMap<>();
set.forEach(valueOfSet->mapSet.put(valueOfSet.substring(0,1).toUpperCase(),valueOfSet));'
return mapSet;
};
System.out.println(function.apply(hs));
}
}
Without Using Function you can do it as below:
Map<String,String> mapSet=new HashMap<>();
hs.forEach(value->mapSet.put(value.substring(0,1),value));
System.out.println(mapSet);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.