2017-10-13 84 views
5

我试图筛选,并通过这样做,减少List<Map<String, Object>>List<String>与Java8新的lambda表达式:减少多阵列列表

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())' –

+1

如果你给我几分钟时间,我可以提供一个更好的例子。 :) – Peter

+0

如果我尝试这个我得到一个'java.lang.ClassCastException:[Ljava.lang.String;不能转换为java.util.List' – Peter

回答

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]

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"))抛出Exception,例如如果map.get("some attribute")不是String[],那么它将被Stream吞下。

+0

可悲的是,你的版本也让我'列表'。 M. le Rutte的回答为我工作。但是,感谢您付出的所有努力(因为我在示例代码中犯了几个错误)。 – Peter

+0

你说得对,'Stream.of'只是返回一个'Stream'作为单个元素,'String []'不是你想要的。我更新了答案。 – user1983983