2017-08-19 49 views
6

Chciałbym przekształcić listę w mapę przy użyciu jako wartości kluczowych tylko dwóch wartości ciągu. Następnie jako wartości właśnie lista ciągów zawierających elementy z pozycji nieparzystej lub parzystej z listy wejściowej. Oto stary kod modowy:Przekształć listę w mapę za pomocą tylko dwóch kluczy i nieparzystych lub parzystych indeksów jako wartości - Java 8 Stream

Map<String, List<String>> map = new HashMap<>(); 

List<String> list = Arrays.asList("one", "two", "three", "four"); 

map.put("evenIndex", new ArrayList<>()); 
map.put("oddIndex", new ArrayList<>()); 
for (int i = 0; i < list.size(); i++) { 
    if(i % 2 == 0) 
     map.get("evenIndex").add(list.get(i)); 
    else 
     map.get("oddIndex").add(list.get(i)); 
} 

Jak przekształcić ten kod na język Java 8 przy użyciu strumieni, aby uzyskać ten wynik?

Moja obecna trudna próba wymaga modyfikacji elementów listy, ale zdecydowanie musi być lepszą opcją.

List<String> listModified = Arrays.asList("++one", "two", "++three", "four"); 

map = listModified.stream() 
      .collect(Collectors.groupingBy(
           str -> str.startsWith("++") ? "evenIndex" : "oddIndex")); 

A może ktoś mi pomoże z tym błędnym rozwiązaniem?

IntStream.range(0, list.size()) 
     .boxed() 
     .collect(Collectors.groupingBy(i -> i % 2 == 0 ? "even" : "odd", 
        Collectors.toMap((i -> i) , i -> list.get(i))))); 

który powróci w ten sposób:

{even={0=one, 2=three}, odd={1=two, 3=four}} 

Odpowiedz

4

Byłaś na dobrej drodze do streamingu na indeksach:

import static java.util.stream.Collectors.groupingBy; 
import static java.util.stream.Collectors.mapping; 
import static java.util.stream.Collectors.toList; 

IntStream.range(0,list.size()) 
     .boxed() 
     .collect(groupingBy(
       i -> i % 2 == 0 ? "even" : "odd", 
       mapping(list::get, toList()) 
     )); 

Jeśli są ok, z mającą swoją mapę być indeksowane przez boolean można użyć: partitioningBy:

IntStream.range(0, list.size()) 
     .boxed() 
     .collect(partitioningBy(
       i -> i % 2 == 0, 
       mapping(list::get, toList()) 
     )); 
1

Możesz osiągnąć to samo z Collectors.toMap; dla zabawy:

Map<String, List<String>> map = IntStream.range(0, list.size()) 
      .boxed() 
      .collect(Collectors.toMap(
        x -> x % 2 == 0 ? "odd" : "even", 
        x -> { 
         List<String> inner = new ArrayList<>(); 
         inner.add(list.get(x)); 
         return inner; 
        }, 
        (left, right) -> { 
         left.addAll(right); 
         return left; 
        }, 
        HashMap::new)); 

    System.out.println(map);