为了账号安全,请及时绑定邮箱和手机立即绑定

如何将单个键值添加到现有的 Java 8 流?

如何将单个键值添加到现有的 Java 8 流?

人到中年有点甜 2023-02-23 18:13:38
这是我填充静态地图的方法public static final Map<String, FooBar> mapEnum = Arrays.stream(FooBarEnum.values())            .collect(Collectors.toMap(e-> StringUtils.upperCase(e.name), e -> e));我想向这张地图添加另一个键值对。mapEnum.put("xx", FooBar.A);这是枚举public enum FooBar {   A("a"), B("b"), C("c");}构建地图后,我的静态地图将如下所示{"a":FooBar.A, "b": FooBar.B, "c": FooBar.C, "xx": Foobar.A}是否可以将显式 put 调用包括在内Collectors.toMap()?
查看完整描述

4 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

如果您愿意使用第三方库,则可以使用Eclipse CollectionsImmutableMap创建静态内联。Stream


public static final ImmutableMap<String, FooBar> MAP_ENUM =
        Arrays.stream(FooBar.values())
                .collect(Collectors2.toMap(FooBar::getName, fooBar -> fooBar))
                .withKeyValue("xx", FooBar.A)
                .toImmutable();public enum FooBar {
    A("a"), B("b"), C("c");    private String name;

    FooBar(String name) {        this.name = name;
    }    public String getName() {        return this.name;
    }
}

您还可以使用本机 Eclipse Collections API 稍微简化代码。

public static final ImmutableMap<String, FooBar> MAP_ENUM =
        ArrayAdapter.adapt(FooBar.values())
                .groupByUniqueKey(FooBar::getName)
                .withKeyValue("xx", FooBar.A)
                .toImmutable();




查看完整回答
反对 回复 2023-02-23
?
莫回无

TA贡献1865条经验 获得超7个赞

实际上,我认为没有必要为此使用 Java Streams。您可以简单地使用该static块来初始化mapEnum它put的附加值:


public static final Map<String, FooBar> mapEnum;


static {

    mapEnum = Arrays.stream(FooBar.values())

            .collect(Collectors.toMap(FooBar::getName, Function.identity()));

    mapEnum.put("xx", FooBar.A);

    // ...

}

Collectors.toMap():不保证返回的 {@code Map} 的类型、可变性、可序列化性或线程安全性。


Map为了确保返回的可变性Collectors.toMap(),以便您Map.put()以后可以更好地使用它:


Arrays.stream(FooBar.values())

        .collect(Collectors.toMap(Function.identity(), Function.identity(), (a, b) -> a, HashMap::new));

如果你真的想使用 java 流,你可以使用这个:


public static final Map<String, FooBar> mapEnum = Stream.concat(

        Stream.of(FooBar.values()).map(e -> Map.entry(e.getName(), e)),

        Stream.of(Map.entry("xx", FooBar.A))

).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

或者,如果您还想将所有名称添加到枚举值本身,您可以像这样更改您的类:


public static enum FooBar {

    A("a", "xx"), B("b"), C("c");


    private String[] names;


    FooBar(String... names) {

        this.names = names;

    }


    public String[] getNames() {

        return names;

    }

}

并使用它来创建地图:


public static final Map<String, FooBar> mapEnum = Stream.of(FooBar.values())

        .flatMap(e -> Arrays.stream(e.getNames()).map(n -> Map.entry(n, e)))

        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

在 Java 9 之前使用new AbstractMap.SimpleEntry<>()而不是Map.entry(). 如果您需要对地图进行排序,请LinkedHashMap::new使用Collectors.toMap().


查看完整回答
反对 回复 2023-02-23
?
qq_花开花谢_0

TA贡献1835条经验 获得超6个赞

您可以使用Collectors::collectAndThen修改结果地图

Arrays.stream(FooBarEnum.values())
        .collect(Collectors.collectAndThen(
                    Collectors.toMap(e-> StringUtils.upperCase(e.name), 
                        Function.identity()), FooBarEnum::addCustom));

以下方法在枚举中

static Map<String, FooBar> addCustom(Map<String, FooBarEnum> map) {
    map.put("xx", FooBar.A);
        return map;
}


查看完整回答
反对 回复 2023-02-23
?
千巷猫影

TA贡献1829条经验 获得超7个赞

您不能直接将它传递给 Collectors.toMap()。您可以在 javadoc 中看到所有可用的覆盖:https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap-java.util.function.Function-java .util.function.Function- .


但是,在使用 Stream.concat 调用 toMap 之前,您可以确保您的流具有构建地图所需的所有对。您连接枚举中的对,以及要添加的手动对。


我的独立代码必须定义 Pair 类,但由于您使用了 StringUtils,我想您有一个已经包含 Pair 的库,因此您不需要定义它。


代码:


import java.util.*;

import java.util.stream.*;


public class Main {


    private static enum  FooBar {

        A("a"), B("b"), C("c");

        private String name;

        FooBar(String name) {

            this.name = name;

        }

    }


    public static class Pair {

        String a;

        FooBar b;

        Pair(String a, FooBar b) {

            this.a = a;

            this.b = b;

        }

    }


    public static void main(String [] args) {

        System.out.println(

            Stream.concat( 

                Arrays.stream(FooBar.values()).map(e -> new Pair(e.name.toUpperCase(), e)),

                Stream.of(new Pair("xx", FooBar.A))

            )

            .collect(Collectors.toMap(pair -> pair.a, pair -> pair.b))

        );

    }


}

输出:


{xx=A, A=A, B=B, C=C}


查看完整回答
反对 回复 2023-02-23
  • 4 回答
  • 0 关注
  • 75 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信