将多个数组减少为列表

时间:2017-10-13 13:34:59

标签: java lambda java-8

我尝试使用Java8新lambdas过滤并将List<Map<String, Object>>缩减为List<String>

List<Map<String, Object>> myObjects = new ArrayList<>();
myObjects.stream()
    .filter(myObject-> myObject.get("some integer value").equals(expectedValue))
    // myObject.get("some attribute") == ["some string", "maybe another string"]
    .map(myObject-> myObject.get("some attribute"))
    .collect(Collectors.toList());

结果是List,但我想将数组中的所有字符串组合成结果List<String>

为了澄清它,这是我现在得到的结果:

ArrayList{["some string"], ["another string"]}

但我想要这个:

ArrayList{"some string", "another string"}

有人可以给我一个提示,我必须将String[]缩减为String吗?我在.map()部分猜它,但我不知道我会在那里改变什么。

修改

如何为测试目的生成List<Map<String, Object>> myObjects

List<Map<String, Object>> myObjects = new ArrayList<>();
Map<String, Object> myObject = new HashMap<>();
myObject.put("some integer value", 1);
String[] theStringIWant = new String[1];
theStringIWant[0] = "Some important information I want";
myObject.put("some attribute", theStringIWant);
myObjects.add(myObject);

看起来像这样:

List<MyObject{"some attribute": 1}>

注意:这只是我的unittest的一个例子。列表规范包含多个元素,每个地图都有更多的属性而不仅仅是some attribute

2 个答案:

答案 0 :(得分:4)

您可能需要另外一个过滤器,但这就是我的方法:

public static void main(String[] args) {
    List<Map<String, Object>> myObjects = new ArrayList<>();
    Map<String, Object> myObject1 = new HashMap<>();

    myObject1.put("some attribute", 1);
    myObject1.put("some string", new String[] { "Some important information I want"});
    myObjects.add(myObject1);

    Map<String, Object> myObject2 = new HashMap<>();
    myObject2.put("some attribute", 1);
    myObject2.put("some string", new String[] { "hello", "world" });
    myObjects.add(myObject2);

    Map<String, Object> myObject3 = new HashMap<>();
    myObject3.put("some attribute", 2);
    myObject3.put("some string", new String[] { "don't", "want", "this"});
    myObjects.add(myObject3);

    Map<String, Object> myObject4 = new HashMap<>();
    myObject4.put("some string", new String[] { "this", "one", "does", "not", "have", "some attribute"});
    myObjects.add(myObject4);

    List<String> list = myObjects.stream()
            .filter(map -> map.containsKey("some attribute"))
            .filter(map -> map.get("some attribute").equals(Integer.valueOf(1)))
            .flatMap(map -> Arrays.stream((String[])map.get("some string")))
            .collect(Collectors.toList());

        System.out.println(list);
    }

结果为[Some important information I want, hello, world]

答案 1 :(得分:3)

您应该能够使用flatMap方法获取Stream String[]而不是map方法:

myObjects.stream()
    .filter(myObject-> myObject.get("some integer value").equals(expectedValue))
    .flatMap(myObject-> Arrays.stream((String[])map.get("some attribute")))
    .collect(Collectors.toList());

但请注意,如果Arrays.stream((String[])map.get("some attribute"))引发Exception,例如如果map.get("some attribute")不是String[],那么它会被Stream吞噬。