一元函数接口中的 HashMap 与 Java 8 中的 Lambda

HashMap in Unary Functional Interface with Lambda in Java 8

我正在学习 Java 8 Lambda 和一元函数接口。我有一个关于 "Function" class 使用 HashMap 的练习作业,需要执行以下步骤:

  1. 创建一个 Function<Set, Map> 类型的变量,它接收一个 Set 并使用 lambda 表达式创建一个 HashMap

  2. 在地图中输入单词,使用该单词的大写首字母作为键

  3. 执行lambda表达式并查看结果

我尝试了以下方法,但它不起作用。我认为问题出在 lambda 表达式中,但我想了解我必须怎么做(为简单起见,我将同一个词作为键)。这样,结果就是"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));
   }
}

对于上面的例子,预期的结果应该是{B=bonjour, C=ciao, H=hello}

我认为这意味着您必须在 Map 中添加 Set 的所有 words 以下 2 条规则

  • 关键是首字母大写
  • 值为单词

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

提示:不要使用原始类型,而是尽可能指定它们:

  • Function<Set,Map> 变为 Function<Set<String>, Map<Character, String>>

我敢打赌你对你的问题有点误解。

您可能需要一个函数来从集合中的每个项目的值中获取键。所以:

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()));

这里假设每个字母只有一个单词。

如果您希望每个第一个字母有多个条目,那么您可以这样做:

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));

如果你想在没有流的情况下做到这一点,它会更复杂但可能:

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));
   }
}

如果不使用函数,您可以按如下方式进行操作:

Map<String,String> mapSet=new HashMap<>();
hs.forEach(value->mapSet.put(value.substring(0,1),value));
System.out.println(mapSet);