没有流/可选的单个对象的Java8方法链接?

时间:2019-05-07 13:03:35

标签: java-8 java-stream optional

通过以下示例,我很容易抓住我的问题。我想对一个对象应用多个转换(在这种情况下,它们都返回相同的类Number,但不一定)。通过Optional(方法3)或Stream(方法4),我可以优雅而清晰地使用.map。但是,当与单个对象一起使用时,我要么只是为了使用.map链(最后带有.get())而设置为Optional,要么最后使用带有findFirst的Stream.of(),这似乎是不必要的工作。

[我的首选项]:我更喜欢方法3和4,因为它们在可读性上似乎比java8之前的选项-方法1和2更好。

[问题]:是否有比这里使用的所有方法更好/更整洁/更可取/更优雅的方法来实现相同效果?如果没有,您将使用哪种方法?

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Tester {

    static class Number {
        private final int value;

        private Number(final int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        @Override
        public String toString() {
            return String.valueOf(value);
        }
    }

    private static Number add(final Number number, final int val) {
        return new Number(number.getValue() + val);
    }

    private static Number multiply(final Number number, final int val) {
        return new Number(number.getValue() * val);
    }

    private static Number subtract(final Number number, final int val) {
        return new Number(number.getValue() - val);
    }

    public static void main(final String[] args) {
        final Number input = new Number(1);

        System.out.println("output1 = " + method1(input)); // 100
        System.out.println("output2 = " + method2(input)); // 100
        System.out.println("output3 = " + method3(input)); // 100
        System.out.println("output4 = " + method4(input)); // 100

        processAList();
    }

    // Processing an object - Method 1
    private static Number method1(final Number input) {
        return subtract(multiply(add(input, 10), 10), 10);
    }

    // Processing an object - Method 2
    private static Number method2(final Number input) {
        final Number added = add(input, 10);
        final Number multiplied = multiply(added, 10);
        return subtract(multiplied, 10);
    }

    // Processing an object - Method 3 (Contrived use of Optional)
    private static Number method3(final Number input) {
        return Optional.of(input)
            .map(number -> add(number, 10))
            .map(number -> multiply(number, 10))
            .map(number -> subtract(number, 10)).get();
    }

    // Processing an object - Method 4 (Contrived use of Stream)
    private static Number method4(final Number input) {
        return Stream.of(input)
            .map(number -> add(number, 10))
            .map(number -> multiply(number, 10))
            .map(number -> subtract(number, 10))
            .findAny().get();
    }

    // Processing a list (naturally uses the Stream advantage)
    private static void processAList() {
        final List<Number> inputs = new ArrayList<>();
        inputs.add(new Number(1));
        inputs.add(new Number(2));

        final List<Number> outputs = inputs.stream()
            .map(number -> add(number, 10))
            .map(number -> multiply(number, 10))
            .map(number -> subtract(number, 10))
            .collect(Collectors.toList());

        System.out.println("outputs = " + outputs); // [100, 110]
    }
}

1 个答案:

答案 0 :(得分:0)

解决方案是将您的方法构建到Number类中。例如:

static class Number {
    // instance variable, constructor and getter unchanged

    public Number add(final int val) {
        return new Number(getValue() + val);
    }

    // mulitply() and subtract() in the same way

    // toString() unchanged
}

现在您的代码变得非常简单易读:

private static Number method5(final Number input) {
    return input
        .add(10)
        .multiply(10)
        .subtract(10);
}

如果愿意,您甚至可以在一行上写return语句:

    return input.add(10).multiply(10).subtract(10);