2017-10-13 129 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