Hej,
chciałem zapytać w jaki sposób najbardziej optymalnie korzystając ze streamów należy przekonwertować jeden z zagnieżdżonych typów na inny filtrując nie nullowe wartości.
Przykładowy kod wyjaśniający o co mi chodzi jest poniżej:
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class DummyTest {
private class A {
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
private class B {
private C c;
public C getC() {
return c;
}
public void setC(C c) {
this.c = c;
}
}
private class C {
private D d;
public D getD() {
return d;
}
public void setD(D d) {
this.d = d;
}
}
private class D {
}
@Test
public void test() {
List<A> data = generateData(100000);
long time1 = System.currentTimeMillis();
List<D> output = data.stream()
.filter(Objects::nonNull)
.map(A::getB)
.filter(Objects::nonNull)
.map(B::getC)
.filter(Objects::nonNull)
.map(C::getD)
.filter(Objects::nonNull)
.collect(Collectors.toList());
long time2 = System.currentTimeMillis();
System.out.println(output.size());
System.out.println(time2 - time1);
}
@Test
public void test1() {
List<A> data = generateData(100000);
long time1 = System.currentTimeMillis();
List<D> output = data.stream()
.filter(input -> {
return input != null && input.getB() != null && input.getB().getC() != null && input.getB().getC().getD() != null;
})
.map(new Function<A, D>() {
@Override
public D apply(A a) {
return a.getB().getC().getD();
}
})
.collect(Collectors.toList());
long time2 = System.currentTimeMillis();
System.out.println(output.size());
System.out.println(time2 - time1);
}
@Test
public void test2() {
List<A> data = generateData(100000);
long time1 = System.currentTimeMillis();
List<D> output = data.stream()
.filter(((Predicate<A>) input -> input.getB() != null).and(input -> input.getB().getC() != null).and(input -> input.getB().getC().getD() != null))
.map(new Function<A, D>() {
@Override
public D apply(A a) {
return a.getB().getC().getD();
}
})
.collect(Collectors.toList());
long time2 = System.currentTimeMillis();
System.out.println(output.size());
System.out.println(time2 - time1);
}
private List<A> generateData(int reapeat) {
List<A> result = new ArrayList<>();
for (int i = 0; i < reapeat; i++) {
A a = new A();
B b = new B();
C c = new C();
D d = new D();
c.setD(d);
b.setC(c);
a.setB(b);
result.add(a);
}
return result;
}
}
Ogolnie wyniki zaprezentowane w linii
System.out.println(time2 - time1);
są zbliżone.
Option<B>
itd.Shalomnieserializowalny
:( i jak tu potem hakować aplikacje jak się payload nie serializuje :(