Java-8流:转换映射<;字符串,列表<;列表<;数据类型>&燃气轮机&燃气轮机;映射<;字符串,列表<;数据类型>&燃气轮机;

Java-8流:转换映射<;字符串,列表<;列表<;数据类型>&燃气轮机&燃气轮机;映射<;字符串,列表<;数据类型>&燃气轮机;,java,java-8,java-stream,Java,Java 8,Java Stream,我刚刚开始研究Java8并尝试lambdas,下面是我想要解决的问题 以下是我目前掌握的代码 Map<String, List<List<DataType>>> a = Arrays.stream(OperatorType.values()) .collect( groupingBy(i -> i.getKey(), mapp

我刚刚开始研究Java8并尝试lambdas,下面是我想要解决的问题

以下是我目前掌握的代码

    Map<String, List<List<DataType>>> a = Arrays.stream(OperatorType.values())
            .collect(
                    groupingBy(i -> i.getKey(), 
                            mapping(i -> i.getSupportedtypes(), 
                                    Collectors.toList()))); 
Map a=Arrays.stream(OperatorType.values())
.收集(
分组依据(i->i.getKey(),
映射(i->i.getSupportedtypes(),
收藏家;
上面的代码片段很有效,但这不是我想要的。我希望它返回
Map

我猜平面映射的某种方法可以解决这个问题

运算符类型枚举以供参考

 public enum OperatorType {

IS_ONE_OF("IS_ONE_OF", 1,
        Collections.singletonList(DataType.ALL)),
IS_NOT_ONE_OF("IS_NOT_ONE_OF", 2,
        Collections.singletonList(DataType.ALL)),
ENDS_WITH("ENDS_WITH", 3,
        Collections.singletonList(DataType.STRING)),
DOES_NOT_ENDS_WITH("DOES_NOT_ENDS_WITH", 4,
        Collections.singletonList(DataType.STRING)),
STARTS_WITH("STARTS_WITH", 5,
        Collections.singletonList(DataType.STRING)),
DOES_NOT_START_WITH("DOES_NOT_START_WITH", 6,
        Collections.singletonList(DataType.STRING)),
MATCHES("MATCHES", 7,
        Collections.singletonList(DataType.STRING)),
DOES_NOT_MATCH("DOES_NOT_MATCH", 8,
        Collections.singletonList(DataType.STRING)),
CONTAINS("CONTAINS", 9,
        Collections.singletonList(DataType.STRING)),
DOES_NOT_CONTAIN("DOES_NOT_CONTAIN", 10,
        Collections.singletonList(DataType.STRING)),
GREATER_THAN("GREATER_THAN", 11, Arrays.asList(DataType.INTEGER,DataType.DOUBLE)), 
GREATER_THAN_OR_EQUAL_TO("GREATER_THAN_OR_EQUAL_TO", 12, Arrays.asList(DataType.INTEGER,DataType.DOUBLE)), 
LESS_THAN("LESS_THAN", 13, Arrays.asList(DataType.INTEGER,DataType.DOUBLE)),
LESS_THAN_OR_EQUAL_TO("LESS_THAN_OR_EQUAL_TO", 15, Arrays.asList(DataType.INTEGER,DataType.DOUBLE)), 
AFTER("AFTER", 15,
        Collections.singletonList(DataType.DATE)),
BEFORE("BEFORE", 16,
        Collections.singletonList(DataType.DATE));

private final int value;

private final String key;

private final List<DataType> supportedtypes;

OperatorType(String key, int value, List<DataType> supportedtypes) {
    this.value = value;
    this.key = key;
    this.supportedtypes = supportedtypes;
}

public int getValue() {
    return this.value;
}

public String getKey() {
    return this.key;
}

public List<DataType> getSupportedtypes() {
    return this.supportedtypes;
}

@Override
public String toString() {
    return String.valueOf(this.value);
}

@JsonCreator
public static OperatorType create(String key) {
    if (key == null) {
        throw new IllegalArgumentException();
    }
    for (OperatorType v : values()) {
        if (v.getKey().equalsIgnoreCase(key)) {
            return v;
        }
    }
    throw new IllegalArgumentException();
}

public static OperatorType fromValue(Integer value) {

    for (OperatorType type : OperatorType.values()) {
        if (value == type.getValue()) {
            return type;
        }
    }
    throw new IllegalArgumentException("Invalid enum type supplied");
}

public static OperatorType fromValue(String key) {

    for (OperatorType type : OperatorType.values()) {
        if (type.getKey().equalsIgnoreCase(key)) {
            return type;
        }
    }
    throw new IllegalArgumentException("Invalid enum type supplied");
}
公共枚举运算符类型{
是的(“是的”,1,
Collections.singletonList(DataType.ALL)),
是不是的(“不是的”,2,
Collections.singletonList(DataType.ALL)),
以结尾(“以结尾”),3,
Collections.singletonList(DataType.STRING)),
不以结尾(“不以结尾”),4,
Collections.singletonList(DataType.STRING)),
以开始(“以开始”),5,
Collections.singletonList(DataType.STRING)),
不以开始(“不以开始”),6,
Collections.singletonList(DataType.STRING)),
匹配(“匹配”),7,
Collections.singletonList(DataType.STRING)),
不匹配(“不匹配”,8,
Collections.singletonList(DataType.STRING)),
包含(“包含”,9,
Collections.singletonList(DataType.STRING)),
不包含(“不包含”),10,
Collections.singletonList(DataType.STRING)),
大于(“大于”,11,Arrays.asList(DataType.INTEGER,DataType.DOUBLE)),
大于或等于(“大于或等于”,12,Arrays.asList(DataType.INTEGER,DataType.DOUBLE)),
小于(“小于”,13,Arrays.asList(DataType.INTEGER,DataType.DOUBLE)),
小于或等于(“小于或等于”,15,Arrays.asList(DataType.INTEGER,DataType.DOUBLE)),
之后(“之后”,15,
Collections.singletonList(DataType.DATE)),
之前(“之前”,16,
Collections.singletonList(DataType.DATE));
私有最终整数值;
私有最终字符串密钥;
私有最终列表支持的类型;
运算符类型(字符串键、int值、列表支持的类型){
这个值=值;
this.key=key;
this.supportedtypes=supportedtypes;
}
public int getValue(){
返回此.value;
}
公共字符串getKey(){
返回此.key;
}
公共列表getSupportedtypes(){
返回此.supportedtypes;
}
@凌驾
公共字符串toString(){
返回字符串.valueOf(this.value);
}
@JsonCreator
公共静态运算符类型创建(字符串键){
if(key==null){
抛出新的IllegalArgumentException();
}
对于(运算符类型v:values()){
if(v.getKey().equalsIgnoreCase(key)){
返回v;
}
}
抛出新的IllegalArgumentException();
}
公共静态运算符type fromValue(整数值){
对于(OperatorType类型:OperatorType.values()){
if(value==type.getValue()){
返回类型;
}
}
抛出新的IllegalArgumentException(“提供的枚举类型无效”);
}
公共静态运算符type fromValue(字符串键){
对于(OperatorType类型:OperatorType.values()){
if(type.getKey().equalsIgnoreCase(key)){
返回类型;
}
}
抛出新的IllegalArgumentException(“提供的枚举类型无效”);
}
}

找到了一种方法:

public static Map<DataType, List<OperatorType>> buildmap() {
    Map<OperatorType, List<DataType>> map = new HashMap<>();

    Arrays.stream(OperatorType.values()).collect(groupingBy(i -> OperatorType.fromValue(i.getKey()),
            mapping(i -> i.getSupportedtypes(), Collectors.toList()))).entrySet().forEach(entry ->
                {
                    map.put(entry.getKey(),
                            entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList()));
                });

    return map.entrySet().stream().flatMap(e -> e.getValue().stream().map(v -> new SimpleEntry<>(v, e.getKey())))
            .collect(
                    Collectors.groupingBy(Entry::getKey, Collectors.mapping(Entry::getValue, Collectors.toList())));
}
publicstaticmap buildmap(){
Map Map=newhashmap();
Arrays.stream(OperatorType.values()).collect(groupingBy(i->OperatorType.fromValue(i.getKey()),
映射(i->i.getSupportedtypes(),Collectors.toList()).entrySet().forEach(条目->
{
map.put(entry.getKey(),
entry.getValue().stream().flatMap(List::stream).collect(Collectors.toList());
});
返回map.entrySet().stream().flatMap(e->e.getValue().stream().map(v->new SimpleEntry(v,e.getKey()))
.收集(
Collectors.groupingBy(Entry::getKey,Collectors.mapping(Entry::getValue,Collectors.toList());
}

您应该能够使用
Stream#flatMap
实现以下目的:

Map<String, List<DataType>> map = new HashMap<>();

a.entrySet().forEach(entry -> {
    map.put(entry.getKey(), entry.getValue().stream()
                                            .flatMap(List::stream)
                                            .collect(Collectors.toList()));
});
Map Map=newhashmap();
a、 entrySet().forEach(条目->{
map.put(entry.getKey(),entry.getValue().stream())
.flatMap(列表::流)
.collect(Collectors.toList());
});

由于
Map
的每个值中
List
List
必须压缩,因此我们必须首先创建一个新的
Map
,然后在压缩每个
List

后重新添加元素。我抛出了一些方法,并在枚举中使用
Integer
关闭了
数据类型,现在看起来是这样的:

enum OperatorType {
    IS_ONE_OF("IS_ONE_OF", 1,
           Collections.singletonList(1)),
    IS_NOT_ONE_OF("IS_NOT_ONE_OF", 2,
           Collections.singletonList(1)),
    ENDS_WITH("ENDS_WITH", 3,
           Collections.singletonList(2)),
    DOES_NOT_ENDS_WITH("DOES_NOT_ENDS_WITH", 4,
           Collections.singletonList(2)),
    STARTS_WITH("STARTS_WITH", 5,
           Collections.singletonList(2)),
    DOES_NOT_START_WITH("DOES_NOT_START_WITH", 6,
           Collections.singletonList(2)),
    MATCHES("MATCHES", 7,
           Collections.singletonList(2)),
    DOES_NOT_MATCH("DOES_NOT_MATCH", 8,
           Collections.singletonList(2)),
    CONTAINS("CONTAINS", 9,
           Collections.singletonList(2)),
    DOES_NOT_CONTAIN("DOES_NOT_CONTAIN", 10,
           Collections.singletonList(2)),
    GREATER_THAN("GREATER_THAN", 11, Arrays.asList(3,4)), 
    GREATER_THAN_OR_EQUAL_TO("GREATER_THAN_OR_EQUAL_TO", 12, Arrays.asList(3,4)), 
    LESS_THAN("LESS_THAN", 13, Arrays.asList(3,4)),
    LESS_THAN_OR_EQUAL_TO("LESS_THAN_OR_EQUAL_TO", 15, Arrays.asList(3,4)), 
    AFTER("AFTER", 15,
           Collections.singletonList(5)),
    BEFORE("BEFORE", 16,
           Collections.singletonList(5));

    private final int value;

    private final String key;

    private final List<Integer> supportedtypes;

    OperatorType(String key, int value, List<Integer> supportedtypes) {
       this.value = value;
       this.key = key;
       this.supportedtypes = supportedtypes;
    }

    public int getValue() {
       return this.value;
    }

    public String getKey() {
       return this.key;
    }

    public List<Integer> getSupportedtypes() {
       return this.supportedtypes;
    }

    @Override
    public String toString() {
       return String.valueOf(this.value);
    }
}
您可以将这两个步骤链接起来。但为了便于阅读,我把它们分开了

对于我来说,打印语句打印以下内容:

DOES_NOT_CONTAIN [2]
STARTS_WITH [2]
LESS_THAN_OR_EQUAL_TO [3, 4]
DOES_NOT_MATCH [2]
AFTER [5]
DOES_NOT_ENDS_WITH [2]
IS_ONE_OF [1]
LESS_THAN [3, 4]
GREATER_THAN_OR_EQUAL_TO [3, 4]
CONTAINS [2]
DOES_NOT_START_WITH [2]
IS_NOT_ONE_OF [1]
BEFORE [5]
GREATER_THAN [3, 4]
ENDS_WITH [2]
MATCHES [2]

1 [2, 1]
2 [7, 3, 6, 9, 4, 8, 5, 10]
3 [11, 12, 13, 15]
4 [11, 12, 13, 15]
5 [16, 15]

我知道这个答案缺少一些解释,但它产生了您想要的
映射一种方法可以是将收集器
列表
替换为更合适的,例如
减少

Map<String, List<DataType>> a = Arrays.stream(OperatorType.values())
  .collect(
    groupingBy(i -> i.getKey(), 
      mapping(i1 -> i1.getSupportedtypes(),
        reducing((List<DataType>) new ArrayList<DataType>(), (l,r) -> {
          List<DataType> list = new ArrayList<DataType>();
          list.addAll(l);
          list.addAll(r);
          return list;
        })))); 
Map a=Arrays.stream(OperatorType.values())
.收集(
分组依据(i->i.getKey(),
映射(i1->i1.getSupportedtypes(),
减少((列表)新ArrayList(),(l,r)->{
列表=新的ArrayList();
列表。添加全部(l);
列表。addAll(r);
退货清单;
})))); 

为了更好的可读性,提取二进制运算符函数可能会有所帮助,例如,
(l,r)->join(l,r)
,其中,
join
连接两个列表。

看起来您的键与枚举名称相同。如果是这样的话:

a) 你根本不需要钥匙;只需使用枚举常量的名称:

public String getKey() {
    return this.name();
}
b) 由于键是唯一的,因此
public String getKey() {
    return this.name();
}
Map<String, List<DataType>> a = Arrays.stream(OperatorType.values())
        .collect(toMap(OperatorType::getKey, OperatorType::getSupportedtypes));