Scy*_*101 4 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> itemList = Arrays.asList(new ItemA("itemA"), new ItemB("itemB"));
Run Code Online (Sandbox Code Playgroud)
就我而言,我无法控制这些类的实现方式,但是我需要将列表分为两个包含相应元素名称的不同列表。
这是包含大量ifand instanceof语句的解决方案的首次尝试:
List<String> itemAList = new ArrayList<>();
List<String> itemBList = new ArrayList<>();
itemList.forEach(item -> {
if(item instanceof ItemA) {
itemAList.add(item.getName());
}
else if(item instanceof ItemB) {
itemBList.add(item.getName());
}
});
Run Code Online (Sandbox Code Playgroud)
因此这可行,但是我对如何避免使用该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());
Run Code Online (Sandbox Code Playgroud)
这也可以,但是这意味着我必须处理两次列表。
正如我说的,我与Item类的实现无关,那么实现这种行为的最佳方法是什么?
问候
[编辑:]谢谢您的所有答复。我今天学到了一些新东西。
您可以根据元素的类别对内容进行分组:
Map<Class, List<String>> grouped = itemList.stream()
.collect(Collectors.groupingBy(Item::getClass,
Collectors.mapping(Item::getName, Collectors.toList())));
Run Code Online (Sandbox Code Playgroud)
并以以下方式访问它:
List<String> itemAList = grouped.get(ItemA.class);
Run Code Online (Sandbox Code Playgroud)