假设我有这 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/