我有一个枚举类
public enum MyEnum {
A("A"),
B("B");
private final String key;
}
字符串
我想生成一个这样的Map:
private Map<MyEnum, MyClass> myMethod(String input) {
Map<MyEnum, MyClass> result = Maps.newHashMap();
for (MyEnum enum : MyEnum.values()) {
Optional<MyClass> value = helper(enum, input);
value.ifPresent(val -> result.put(enum, val));
}
return result;
}
型
我是lambda/stream的新手,我们可以把它重构为这样的东西吗?
private Map<MyEnum, MyClass> myMethod(String input) {
return MyEnum.values().stream().map(...).collect(Collector.toMap(...));
}
型
我尝试使用Arrays.stream()...
,但最后当我使用collect(Collector.toMap(Map.Entry::getKey, Map.Entry::getValue)
时,它有一些静态与非静态的问题
2条答案
按热度按时间bkhjykvo1#
tl;干
个字符
详情
让我们让你的示例代码更具体。我们称之为
CodeLetter
而不是MyEnum
。我们使用java.time.DayOfWeek
而不是MyClass
。首先,似乎
key
字段只是一个干扰,与您的问题无关。因此我们将其简化为一个简单的枚举声明。型
我们为你提到的
helper
类提供了一个实现。传递一个CodeLetter
枚举对象,得到一个DayOfWeek
对象。型
现在完全实现构建Map的示例方法。
myMethod
重命名为buildMap
。result
重命名为map
。Maps.newHashMap
,所以我们用一个实现Map
的特定类来代替它。当你有一个枚举作为你的Map键时,使用高度优化的EnumMap
类。Optional<MyClass>
,在我们的新命名下将是Optional<CodeLetter>
。但是Optional
通常最好只用作返回类型。在我们这里的例子中,EnumMap
允许map值为null。所以我们放弃了Optional
,而是使用简单的null。型
练习这个代码。
型
运行时:
map = {A=SATURDAY,B=SUNDAY,C=null}
很好,代码成功运行。
回到你的问题的核心。你似乎想重构
buildMap
方法以使用流而不是我们的for
循环。很好。让我们创建一个buildMapByStream
方法,作为替代实现。要通过流来构建map,首先获取我们的key
CodeLetter
的值的流。然后在该流上调用collect
。我们向collect
方法传递一个Collector
实现。Java通过Collectors.toMap
方法提供一个。我们向toMap
方法传递四个参数:一个lambda用于生成每个Map键,一个lambda用于生成每个Map值,一个lambda用于解决任何冲突,以及一个lambda用于构造我们选择的结果Map
实现。型
我们可以简化前两个论点。
Function
实现,它提供了相同的功能:Function.identity
。helper
方法。我们可以用method reference,this :: helper
来代替它。在这些更改之后,我们的代码看起来像这样:
型
我们应该可以认为工作已经完成了。不幸的是,Java 8到21在
Collectors.toMap
中有a known bug,当生成的map值为null时,会抛出NullPointerException
。参见kajacx的this Question和this Answer。幸运的是,Answer提供了一个替代
Collectors.toMap
的解决方案。型
在这一点上,我们可以练习
buildMapByStream
方法。map = {A=SATURDAY,B=SUNDAY,C=null}
很好,工作完成了。
下面是完整的代码,以方便您的复制粘贴。
2g32fytz2#
尝试以下操作。
字符串