Java 在给定一个函数和一组参数的情况下,是否有一种简单的方法来创建反向映射?

Java 在给定一个函数和一组参数的情况下,是否有一种简单的方法来创建反向映射?,java,java-8,Java,Java 8,假设我们有一个将X映射到Y的纯方法: public abstract Y map(X x); 有没有简单的方法来创建从函数到映射到这些函数的参数集的反向映射?也就是说,要从集合创建映射。简而言之,我指的是比直截了当的方法更简单的库解决方案: public Map<Y, Set<X>> reverseMapping(Set<X> arguments) { Map<Y, Set<X>> answer = new HashMap&l

假设我们有一个将X映射到Y的纯方法:

public abstract Y map(X x);
有没有简单的方法来创建从函数到映射到这些函数的参数集的反向映射?也就是说,要从
集合
创建
映射
。简而言之,我指的是比直截了当的方法更简单的库解决方案:

public Map<Y, Set<X>> reverseMapping(Set<X> arguments) {
    Map<Y, Set<X>> answer = new HashMap<>();
    arguments.forEach(x->{
        Y y = map(x);
        if (!answer.containsKey(y)) {
            answer.put(y, new HashSet<>());
        }
        answer.get(y).put(x);
    });
    return answer;
}
公共映射反向映射(设置参数){
Map answer=new HashMap();
参数。forEach(x->{
Y=map(x);
如果(!应答.容器y(y)){
put(y,newhashset());
}
回答:得到(y),放(x);
});
返回答案;
}

Java 8中添加了很多函数式编程功能,我想这可能就是我需要的功能。

对于此类任务,有一个简单的解决方案。虽然单参数版本生成一个
映射,但您始终可以提供一个
函数
作为参数,那么编程模型就很好了

public <X, Y> Map<Y, Set<X>> reverseMapping(Set<X> arguments, Function<X, Y> fn) {
    return arguments.stream()
            .collect(
                    Collectors.groupingBy(
                            fn, // The "map" invocation
                            Collectors.toSet()));
}

@Test
public void testFn() {
    final Set<String> cities = 
        Stream.of("NYC", "Los Angeles", "San Fransisco")
              .collect(Collectors.toSet());

    final Map<String, Set<String>> reversed = 
        reverseMapping(cities, city -> mapState(city));

    System.out.println(reversed); // -> {NY=[NYC], California=[San Fransisco, Los Angeles]}

}

// This is one version of a "map"-method as provided by the OP
private String mapState(String city) {
    switch (city) {
        case "NYC":
            return "NY";
        case "Los Angeles":
        case "San Fransisco":
            return "California";
    }
    return "Unknown";
}
公共映射反向映射(设置参数,函数fn){
返回参数。stream()
.收集(
收集者分组(
fn,//映射调用
Collectors.toSet());
}
@试验
公共无效测试fn(){
最终设定城市=
溪流(“纽约”、“洛杉矶”、“旧金山”)
.collect(收集器.toSet());
最终映射反转=
反向映射(城市,城市->映射状态(城市));
System.out.println(反向);//->{NY=[NYC],加利福尼亚=[San Fransisco,Los Angeles]}
}
//这是OP提供的“映射”方法的一个版本
私有字符串映射状态(字符串城市){
交换机(城市){
案例“纽约”:
返回“NY”;
“洛杉矶”案:
案例“圣弗朗西斯科”:
返回“加利福尼亚”;
}
返回“未知”;
}

基本上,您可以提供自己的映射方法作为lambda。

注意,即使是手动收集代码也可以使用Java8API
参数进行改进
public <X, Y> Map<Y, Set<X>> reverseMapping(Set<X> arguments, Function<X, Y> fn) {
    return arguments.stream()
            .collect(
                    Collectors.groupingBy(
                            fn, // The "map" invocation
                            Collectors.toSet()));
}

@Test
public void testFn() {
    final Set<String> cities = 
        Stream.of("NYC", "Los Angeles", "San Fransisco")
              .collect(Collectors.toSet());

    final Map<String, Set<String>> reversed = 
        reverseMapping(cities, city -> mapState(city));

    System.out.println(reversed); // -> {NY=[NYC], California=[San Fransisco, Los Angeles]}

}

// This is one version of a "map"-method as provided by the OP
private String mapState(String city) {
    switch (city) {
        case "NYC":
            return "NY";
        case "Los Angeles":
        case "San Fransisco":
            return "California";
    }
    return "Unknown";
}