0
if(obj.getAttribute() != null) {
    newobject.setAttribute(obj.getAttribute());
    }
if(obj.getAttribute() != null) {
        newobject.setAttribute(obj.getAttribute());
}
if(obj.getAttribute() != null) {
        newobject.setAttribute(obj.getAttribute());
}

Imagine this code at scale - mapping an object with 15+ attributes. How do I reduce cognitive complexity without splitting the mapping in two/three parts which increases the cognitive complexity overall.

Robert
  • 78
  • 1
  • 8

2 Answers2

2

You might use Optional like

newobject.setAttribute(
    Optional.ofNullable(obj.getAttribute()).orElse("your_default_value")
);

But it depends of what should happen when obj.getAttribute() is empty ?
From what is provided newobject.attribute will be empty anyway, assigning property from parent does not require null-check.

IQbrod
  • 2,060
  • 1
  • 6
  • 28
  • 2
    You could also reverse this logic by doing: Optional.ofNullable(obj.getAttribute).ifPresent(newobject::setAttribute); This allows the default value to remain whatever newobject originally had – ODDminus1 Jan 24 '23 at 10:39
0

You can use mapstruct, as the comment says. If, for any reason you don't want to (e.g. because mapstruct uses reflection, which can be slightly inefficient), then you can use a map.

Supposing you have two classes like this:

class A {
    Integer getAttribute1() { return null; }
    String getAttribute2() { return ""; }
}

class B {
    void setAttribute1(Integer x) {}
    void setAttribute2(String x) {}
}

Then you could define a map like this:

private static Map<Function<A, ?>, BiConsumer<B, Object>> mapOfAtoB = Map.of(
        A::getAttribute1, (b, x) -> b.setAttribute1((Integer) x),
        A::getAttribute2, (b, x) -> b.setAttribute2((String) x));

and use it like this:

void copyAtoB(A a, B b) {
    mapOfAtoB.forEach((fA, fB) -> {
        Object o = fA.apply(a);
        if (o != null)
            fB.accept(b, o);
    });
k314159
  • 5,051
  • 10
  • 32