Java流功能转换/丰富数据

huangapple go评论85阅读模式
英文:

Java Streams functional transform / enrich data

问题

我想编写一个将DataX转换/丰富为List<DataY>的函数

class DataX {
    private String a;
    private List<String> c;
}

class DataY {
    private String a;
    private String b;
    private String cx;
}

JSON表示

输入

{
    "a": "abc-123",
    "c": ["c1", "c2", "c3", "c4", "c5"]
}

在处理c的每个元素时,将检查其值与查找表进行对比(可以是数据库、本地缓存或REST查询),并且一些值从1映射到多个。

c1 -> c1 
c2 -> c2 
c3 -> c31, c32, c33 
c4 -> c4 
c5 -> c51, c52

期望的输出,

[
    {
        "a": "abc-123",
        "b": "xyz-1",
        "cx": "c1"
    },
    {
        "a": "abc-123",
        "b": "xyz-2",
        "cx": "c2"
    },
    {
        "a": "abc-123",
        "b": "xyz-3",
        "cx": "c31"
    },
    {
        "a": "abc-123",
        "b": "xyz-4",
        "cx": "c32"
    },
    {
        "a": "abc-123",
        "b": "xyz-5",
        "cx": "c33"
    },
    {
        "a": "abc-123",
        "b": "xyz-6",
        "cx": "c4"
    },
    {
        "a": "abc-123",
        "b": "xyz-7",
        "cx": "c51"
    },
    {
        "a": "abc-123",
        "b": "xyz-8",
        "cx": "c52"
    }
]

注意:值b代表通过UUID.randomUUID()方法生成的UUID


我的尝试

public class Test {
    public static void main(String[] args) {
        DataX dataX = new DataX("abc-123", Arrays.asList("c1", "c2", "c3", "c4", "c5"));

        List<DataY> collect = dataX.getC().stream()
                .map(c -> new DataY(dataX.getA(), UUID.randomUUID().toString(), c))
                .map(dataY -> {
                    if (isOneToMany(dataY.getCx()))
                        return operationOneToMany(dataY.getCx());
                    else
                        return dataY.getCx();
                })
                .collect(Collectors.toList());
    }

    private static boolean isOneToMany(String input) {
        return (Arrays.asList("c3", "c5").contains(input));
    }

    private static Optional<List<String>> operationOneToMany(String input) {
        if ("c3".equals(input))
            return Optional.of(Arrays.asList("c31", "c32", "c33"));
        else if ("c5".equals(input))
            return Optional.of(Arrays.asList("c51", "c52"));
        else
            return Optional.empty();
    }
}

顺便提一下,它不起作用


可工作的代码,但不确定是否优化

public class Test2 {
    public static void main(String[] args) {
        DataX dataX = new DataX("abc-123", Arrays.asList("c1", "c2", "c3", "c4", "c5"));
        System.out.println("dataX = " + dataX);

        List<DataY> collect = dataX.getC().stream()
                .map(c -> operationOneToMany(c))
                .flatMap(e -> e.stream())
                .map(c -> new DataY(dataX.getA(), UUID.randomUUID().toString(), c))
                .collect(Collectors.toList());

        System.out.println("collect = " + collect);
    }

    private static List<String> operationOneToMany(String input) {
        if ("c3".equals(input))
            return Arrays.asList("c31", "c32", "c33");
        else if ("c5".equals(input))
            return Arrays.asList("c51", "c52");
        else
            return Arrays.asList(input);
    }
}
英文:

I want to write a DataX to List&lt;DataY&gt; transform/enrich function

class DataX {
    private String a;
    private List&lt;String&gt; c;
}

class DataY {
    private String a;
    private String b;
    private String cx;
}

JSON representation

Input

{
    &quot;a&quot;: &quot;abc-123&quot;,
    &quot;c&quot;: [&quot;c1&quot;, &quot;c2&quot;, &quot;c3&quot;, &quot;c4&quot;, &quot;c5&quot;]
}

As processing each element of c the value is checked against a lookup table (can be a database, local cache, or REST lookup) and some get mapped from 1 to many.

c1 -&gt; c1 
c2 -&gt; c2 
c3 -&gt; c31, c32, c33 
c4 -&gt; c4 
c5 -&gt; c51, c52

Expected output,

[
    {
        &quot;a&quot;: &quot;abc-123&quot;,
        &quot;b&quot;: &quot;xyz-1&quot;,
        &quot;cx&quot;: &quot;c1&quot;
    },
    {
        &quot;a&quot;: &quot;abc-123&quot;,
        &quot;b&quot;: &quot;xyz-2&quot;,
        &quot;cx&quot;: &quot;c2&quot;
    },
    {
        &quot;a&quot;: &quot;abc-123&quot;,
        &quot;b&quot;: &quot;xyz-3&quot;,
        &quot;cx&quot;: &quot;c31&quot;
    },
    {
        &quot;a&quot;: &quot;abc-123&quot;,
        &quot;b&quot;: &quot;xyz-4&quot;,
        &quot;cx&quot;: &quot;c32&quot;
    },
    {
        &quot;a&quot;: &quot;abc-123&quot;,
        &quot;b&quot;: &quot;xyz-5&quot;,
        &quot;cx&quot;: &quot;c33&quot;
    },
    {
        &quot;a&quot;: &quot;abc-123&quot;,
        &quot;b&quot;: &quot;xyz-6&quot;,
        &quot;cx&quot;: &quot;c4&quot;
    },
    {
        &quot;a&quot;: &quot;abc-123&quot;,
        &quot;b&quot;: &quot;xyz-7&quot;,
        &quot;cx&quot;: &quot;c51&quot;
    },
    {
        &quot;a&quot;: &quot;abc-123&quot;,
        &quot;b&quot;: &quot;xyz-8&quot;,
        &quot;cx&quot;: &quot;c52&quot;
    }
]

> Note: Value b represent UUIDs generated via UUID.randomUUID() method


My attempt

public class Test {
    public static void main(String[] args) {
        DataX dataX = new DataX(&quot;abc-123&quot;, Arrays.asList(&quot;c1&quot;, &quot;c2&quot;, &quot;c3&quot;, &quot;c4&quot;, &quot;c5&quot;));

        List&lt;DataY&gt; collect = dataX.getC().stream()
                .map(c -&gt; new DataY(dataX.getA(), UUID.randomUUID().toString(), c))
                .map(dataY -&gt; {       // use flatMap here?
                    if (isOneToMany(dataY.getCx()))
                        return operationOneToMany(dataY.getCx());
                    else
                        return dataY.getCx();
                })
                .collect(Collectors.toList());
    }

    private static boolean isOneToMany(String input) {
        return (Arrays.asList(&quot;c3&quot;, &quot;c5&quot;).contains(input));
    }

    // Shall I apply this to each element, and return list of 1 or list of many elements 
    private static Optional&lt;List&lt;String&gt;&gt; operationOneToMany(String input) {
        if (&quot;c3&quot;.equals(input))
            return Optional.of(Arrays.asList(&quot;c31&quot;, &quot;c32&quot;, &quot;c33&quot;));
        else if (&quot;c5&quot;.equals(input))
            return Optional.of(Arrays.asList(&quot;c51&quot;, &quot;c52&quot;));
        else
            return Optional.empty();
    }

}

> BTW, it's not working


Working code but not sure if optimised

public class Test2 {
    public static void main(String[] args) {
        DataX dataX = new DataX(&quot;abc-123&quot;, Arrays.asList(&quot;c1&quot;, &quot;c2&quot;, &quot;c3&quot;, &quot;c4&quot;, &quot;c5&quot;));
        System.out.println(&quot;dataX = &quot; + dataX);

        List&lt;DataY&gt; collect = dataX.getC().stream()
                .map(c -&gt; operationOneToMany(c))
                .flatMap(e -&gt; e.stream())
                .map(c -&gt; new DataY(dataX.getA(), UUID.randomUUID().toString(), c))
                .collect(Collectors.toList());

        System.out.println(&quot;collect = &quot; + collect);
    }

    private static List&lt;String&gt; operationOneToMany(String input) {
        if (&quot;c3&quot;.equals(input))
            return Arrays.asList(&quot;c31&quot;, &quot;c32&quot;, &quot;c33&quot;);
        else if (&quot;c5&quot;.equals(input))
            return Arrays.asList(&quot;c51&quot;, &quot;c52&quot;);
        else
            return Arrays.asList(input);
    }

}

答案1

得分: 1

按照 @Rono 的建议

public class Test2 {
    public static void main(String[] args) {
        DataX dataX = new DataX("abc-123", Arrays.asList("c1", "c2", "c3", "c4", "c5"));
        System.out.println("dataX = " + dataX);

        List<DataY> collect = dataX.getC().stream()
                .flatMap(e -> operationOneToMany(e).stream())
                .map(c -> new DataY(dataX.getA(), UUID.randomUUID().toString(), c))
                .collect(Collectors.toList());

        System.out.println("collect = " + collect);
    }

    private static List<String> operationOneToMany(String input) {
        if ("c3".equals(input))
            return Arrays.asList("c31", "c32", "c33");
        else if ("c5".equals(input))
            return Arrays.asList("c51", "c52");
        else
            return Arrays.asList(input);
    }
}
英文:

As suggested by @Rono

public class Test2 {
    public static void main(String[] args) {
        DataX dataX = new DataX(&quot;abc-123&quot;, Arrays.asList(&quot;c1&quot;, &quot;c2&quot;, &quot;c3&quot;, &quot;c4&quot;, &quot;c5&quot;));
        System.out.println(&quot;dataX = &quot; + dataX);

        List&lt;DataY&gt; collect = dataX.getC().stream()
                .flatMap(e -&gt; operationOneToMany(e).stream())
                .map(c -&gt; new DataY(dataX.getA(), UUID.randomUUID().toString(), c))
                .collect(Collectors.toList());

        System.out.println(&quot;collect = &quot; + collect);
    }

    private static List&lt;String&gt; operationOneToMany(String input) {
        if (&quot;c3&quot;.equals(input))
            return Arrays.asList(&quot;c31&quot;, &quot;c32&quot;, &quot;c33&quot;);
        else if (&quot;c5&quot;.equals(input))
            return Arrays.asList(&quot;c51&quot;, &quot;c52&quot;);
        else
            return Arrays.asList(input);
    }

}

huangapple
  • 本文由 发表于 2020年8月26日 03:04:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63585537.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定