我想使用Java 8的流和lambdas将对象列表转换为Map .
这就是我在Java 7及以下版本中编写它的方法 .
private Map<String, Choice> nameMap(List<Choice> choices) {
final Map<String, Choice> hashMap = new HashMap<>();
for (final Choice choice : choices) {
hashMap.put(choice.getName(), choice);
}
return hashMap;
}
我可以使用Java 8和Guava轻松完成此任务,但我想知道如何在没有Guava的情况下完成此操作 .
在 Guava :
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, new Function<Choice, String>() {
@Override
public String apply(final Choice input) {
return input.getName();
}
});
}
和 Guava 与Java 8 lambdas .
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, Choice::getName);
}
17 回答
我用这个语法
我试图这样做,并发现,使用上面的答案,当使用
Functions.identity()
作为Map的键时,我遇到了使用像this::localMethodName
这样的本地方法因为输入问题而实际工作的问题 .Functions.identity()
实际上对这种情况下的输入做了一些事情,所以该方法只能通过返回Object
并接受Object
的参数来工作为了解决这个问题,我最终放弃
Functions.identity()
并改为使用s->s
.所以我的代码,在我的情况下列出目录中的所有目录,并为每个目录使用目录的名称作为 Map 的键,然后调用具有目录名称的方法并返回项目的集合,如下所示:
可以使用流来执行此操作 . 为了消除显式使用
Collectors
的需要,可以静态导入toMap
(按照Effective Java,第三版的建议) .这可以通过两种方式完成 . 让人成为我们将要用来演示它的课程 .
设 persons 是要转换为 Map 的人员列表
1.在列表中使用简单的foreach和Lambda表达式
2.在给定列表上定义的Stream上使用收集器 .
例如,如果要将对象字段转换为映射:
示例对象:
并且操作转换List To Map:
我将编写如何使用 generics 和 inversion of control 将列表转换为映射 . 只是 universal method!
Maybe 我们有 list of Integers 或 objects. 列表所以问题如下:应该是什么 key of the map?
创建界面
现在使用控制反转:
例如,如果我们有书的对象,这个类就是为 Map 选择键
列出的大部分答案都错过了 list has duplicate items 的情况 . 在那种情况下,答案会抛出
IllegalStateException
. 请参阅以下代码 to handle list duplicates :这是StreamEx的解决方案
如果您不想使用Collectors.toMap(),这是另一个
使用getName()作为键和选择本身作为映射的值:
基于Collectors documentation,它很简单:
如果您的密钥 NOT 保证对列表中的所有元素都是唯一的,则应将其转换为
Map<String, List<Choice>>
而不是Map<String, Choice>
如果您没有't mind using 3rd party libraries, AOL' lib(披露我是贡献者),所有JDK Collection类型都有扩展名,包括List和Map .
您可以使用IntStream创建索引流,然后将它们转换为Map:
甚至为我这个目的,