将多个数组合并为一个列表

5

我正在尝试使用Java8新的lambda表达式将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<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}>

注意:这只是我的单元测试的一个示例。列表通常包含多个元素,每个映射都有更多属性,而不仅仅是some attribute


3
没有看到你的原始“Map”很难判断,但你可能需要使用.flatmap(myObject-> ((List) myObject.get("list")).stream()) - tobias_k
1
如果您能给我一些时间,我可以提供一个更好的例子,包括实际列表。 :) - Peter
如果我尝试这样做,我会得到一个java.lang.ClassCastException:[Ljava.lang.String;无法转换为java.util.List - Peter
1
我认为你的最终结果不正确,因为你正在覆盖与键“某个属性”相关联的值。 无论如何,重点是你有一个MapList,每个Map包含任何类型的值,如果它恰好是一个String数组,你想把它的所有元素放入结果List中? - user1983983
1
然后尝试使用flatmap(myObject-> Stream.of(myObject.get("list"))。但是,我不明白你的示例映射如何适用于你的原始代码。"list"键在哪里? - tobias_k
显示剩余5条评论
2个回答

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);
    }

结果是 [我想要的一些重要信息,你好,世界]


3

你可以使用 flatMap 方法返回一个 String[] 类型的 Stream,而不是使用 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")) 抛出异常,比如map.get("some attribute")不是一个String[],那么它会被 Stream 忽略。


很遗憾,您的版本也会得到List<String[]>。M. le Rutte的答案对我有用。但是感谢您所付出的所有努力(因为我在示例代码中犯了几个错误)。 - Peter
你是对的,Stream.of 只返回一个 Stream,其中 String[] 是单个元素,这不是你想要的。我更新了答案。 - user1983983

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接