Java8按类划分的独立列表元素
假设我有一个从同一基类继承的项目列表:Java8按类划分的独立列表元素,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,假设我有一个从同一基类继承的项目列表: class Item { protected String name; public Item(String name) { this.name = name; } getName() { return name; } } class ItemA extends Item {...} class ItemB extends Item {...} List<Item> itemL
class Item {
protected String name;
public Item(String name) {
this.name = name;
}
getName() {
return name;
}
}
class ItemA extends Item {...}
class ItemB extends Item {...}
List<Item> itemList = Arrays.asList(new ItemA("itemA"), new ItemB("itemB"));
这是可行的,但我对如何避免if
语句进行了一些思考。因为我使用的是Java 8,所以我可以这样做:
List<String> itemAList = itemList.stream()
.filter(ItemA.class::isInstance)
.map(item -> item.getName())
.collect(Collectors.toList());
List<String> itemBList = itemList.stream()
.filter(ItemB.class::isInstance)
.map(item -> item.getName())
.collect(Collectors.toList());
List itemList=itemList.stream()
.filter(ItemA.class::isInstance)
.map(项目->项目.getName())
.collect(Collectors.toList());
List itemBList=itemList.stream()
.filter(ItemB.class::isInstance)
.map(项目->项目.getName())
.collect(Collectors.toList());
这同样有效,但这意味着我必须处理列表两次
正如我所说,我与项的实现无关,那么实现这种行为的最佳方式是什么呢
问候
[编辑:]感谢您的回复。我今天学到了一些新东西。正如你所说,你有不同的实例,你无法控制,因此你不能确定列表中只出现ItemA
和ItemB
您最好使用一个映射,它以名称作为键,以项的列表作为值:
Map<String, List<Item>> map = itemList.stream()
.collect(Collectors.groupingBy(Item::getName, Function.identity()));
Map Map=itemList.stream()
.collect(Collectors.groupingBy(Item::getName,Function.identity());
您可以根据元素的类别对内容进行分组:
Map<Class, List<String>> grouped = itemList.stream()
.collect(Collectors.groupingBy(Item::getClass,
Collectors.mapping(Item::getName, Collectors.toList())));
Map group=itemList.stream()
.collect(收集器).groupingBy(项::getClass,
Collectors.mapping(Item::getName,Collectors.toList());
并通过以下方式访问:
List<String> itemAList = grouped.get(ItemA.class);
List itemAList=grouped.get(ItemA.class);
您还可以执行以下操作:
Map<Boolean, List<Item>> classMap = itemList.stream()
.collect(Collectors.partitioningBy(ItemA.class::isInstance));
Collectors.partitioningBy
如果您知道只有两种类型,如果不是Collectors.groupingBy
@Naman如果您知道只有两种类型,则流api中只有两个可能键的专用映射;但除此之外,我更新了comment@Eugene我指出这一点的唯一原因(在评论编辑之前)分区使用了一个谓词
,并且表示类的条件要么是ItemA
,要么其他任何东西都不能进一步扩展。请注意,如果ItemA
或ItemB
已经是子类,那么getClass
和instanceof
的作用就不同了……谢谢您的帮助。这大大清理了我的代码。
Map<Boolean, List<Item>> classMap = itemList.stream()
.collect(Collectors.partitioningBy(ItemA.class::isInstance));
{
false=[ItemB [getClass()=class stackoverflow.ItemB]],
true =[ItemA [getClass()=class stackoverflow.ItemA]]
}