lambda - List<Base> 到 List<Long> ... 条件转换

标签 lambda java-8 type-conversion java-stream predicate

假设我有这 3 个类(大大减少):

public interface Base
{
    String getType();
}

public class Object1 implements Base
{
    String getType() { ... };

    long getSerialNr() { ... };
}

public class Object2 implements Base
{
    String getType() { ... };

    long getPartNr() { ... };
}

我将如何(使用 Java 8 流)转换 List<Base>List<Long>使用条件转换?我从这个开始:

List<Long> result = baseList.stream().filter(Objects::nonNull)
    .filter(Object1.class::isInstance)
    .map(Object1.class::cast)
    .map(o -> o.getSerialNr())
    .collect(Collectors.toList());

...但是我如何整合第二种情况,其中元素是 Object2 的一个实例我想返回 getPartNr

最佳答案

假设类的数量可能会增长,你可能不得不抽象类型到属性的映射:

static Map<Predicate<Base>,Function<Base,Long>> ACCESSORS;
static {
    Map<Predicate<Base>,Function<Base,Long>> m=new HashMap<>();
    m.put(Object1.class::isInstance, base -> ((Object1)base).getSerialNr());
    m.put(Object2.class::isInstance, base -> ((Object2)base).getPartNr());
    ACCESSORS=Collections.unmodifiableMap(m);
}
static Stream<Long> get(Base b) {
    return ACCESSORS.entrySet().stream()
            .filter(e -> e.getKey().test(b))
            .map(e -> e.getValue().apply(b));
}

get 方法假定谓词是互斥的,在测试这些非interface 类型时就是这种情况。

然后,您可以像这样使用它:

List<Long> result = baseList.stream()
    .flatMap(YourClass::get)
    .collect(Collectors.toList());

您也可以内联 get 方法,但这并没有提高可读性:

List<Long> result = baseList.stream()
    .flatMap(b -> ACCESSORS.entrySet().stream()
        .filter(e -> e.getKey().test(b))
        .map(e -> e.getValue().apply(b)))
    .collect(Collectors.toList());

关于lambda - List<Base> 到 List<Long> ... 条件转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39225186/

相关文章:

android - 如何在 minsdk <24 上将 Kotlin 与 Butterknife 10.1.0 一起使用?

c# - 将存储在整数列表(小端)中的二进制表示形式转换为 Biginteger

c++ - 为什么 C++1 1's lambda require "mutable"关键字默认用于按值捕获?

c# - 使用 View 中的模型,lambda表达式解释

c++ - 'auto ... arg' 的参数包形式在 lambda 中启用但在函数中没有启用?

c++ - 处理作用域变量的内部函数

java - 具有日期和时间的计时器 Java 8

java - 如何编写没有括号的ArrayList

python - Cython 与 Python3.5 : convert list of string to char**

arrays - 在 Go 中将固定大小的数组转换为可变大小的数组