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]]
 }