2017-10-13 75 views
5

próbuję filtrować i zmniejszenia List<Map<String, Object>> do List<String> z Java8 nowych lambdas w ten sposób:Zmniejszyć wiele tablic do listy

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

Rezultatem jest lista, ale chcę, aby połączyć wszystkie sznurki wewnątrz tablica do wynikowego List<String>.

Aby wyjaśnić to, jest to wynik Dostaję teraz:

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

Ale chcę to:

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

Czy ktoś może mi dać wskazówkę, w którym część muszę zmniejszyć String[] do String? Zgaduję, że to jest na części .map(), ale nie wiem, co tam zmienię.

edit:

To jak List<Map<String, Object>> myObjects mogą być generowane dla celów testowania:

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

który wygląda tak:

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

Uwaga: To tylko przykład z mojego unittest. Lista normalnie zawiera więcej niż jeden element, a każda mapa ma więcej atrybutów, a nie tylko some attribute.

+3

trudno powiedzieć, nie widząc oryginalny 'Map', ale prawdopodobnie need '.flatmap (myObject-> ((Lista) myObject.get (" list ")). stream())' –

+1

Jeśli dasz mi kilka minut, mogę podać lepszy przykład z rzeczywistą listą. :) – Peter

+0

Jeśli spróbuję tego, otrzymuję 'java.lang.ClassCastException: [Ljava.lang.String; nie można rzutować na java.util.List' – Peter

Odpowiedz

4

Możecie mieć inny filtr, ale to jest jak bym uczynić go:

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

Rezultatem jest [Some important information I want, hello, world]

3

Powinieneś być w stanie uzyskać, że metodą flatMap z przekazaniem Stream z String[] zamiast metody map:

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

Ale należy pamiętać, że jeśli Arrays.stream((String[])map.get("some attribute")) zgłasza Exception, np jeśli map.get("some attribute") nie jest String[], to zostanie połknięty przez Strumień.

+0

Niestety, twoja wersja również mnie "List ". Odpowiedź od M. le Rutte działa u mnie. Ale dziękuję za cały wysiłek, jaki musieliście włożyć w to (ponieważ popełniłem kilka błędów w moim przykładowym kodzie). – Peter

+0

Masz rację, 'Stream.of' po prostu zwraca' Stream' z 'String []' jako pojedynczym elementem, który nie jest tym, czego potrzebujesz. Zaktualizowałem odpowiedź. – user1983983