2016-04-17 18 views
1

Ich habe eine Liste von 1D-Arrays in ein Objekt gewickelt, ich möchte sie in 1 einzigen Array mit Java-8-Stream sammeln und sammeln.Verketten Liste von Objekten Arrays in Java8

Gegeben Klasse Artikel mit einer Reihe von

class A{ 
int x; 
} 


class Item{ 
    A[] parts=new A[]; 
    public A[] getParts(){ 
     return parts; 
    } 
} 

Also, wenn ich Liste l

List<Item> l=new ArrayList<>(); 
l.add(new Item()); 
l.add(new Item()); 

Ich brauche den Inhalt in diesem beide Objekt in einem einzigen Array vom Typ A zu sammeln

Also wenn das erste Element parts={1,2} und das zweite Element parts={3,4} hat, sollte die Ausgabe irgendwie wie

sein
A[] out={1,2,3,4} 

Ich versuchte

l.stream().map(Item::getParts).collect(Collectors.toList()).toArray(new A[n]); 

zu tun, aber apperantly hat es meany Probleme.

+3

ich meine Antwort gelöscht, werden Sie mehr erfahren durch die Stream-Tutorial lesen https://docs.oracle .com/javase/tutorial/sammlungen/ströme /. Dein Code wird nicht kompiliert. – Tunaki

+1

Ihre Methode heißt 'getParts()', nicht 'getparts()'. Und streamen Sie als [toArray()] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#toArray-java.util.function.IntFunction-) -Methode sowie eine flatMap() -Methode. –

+2

Um die Elemente eines Arrays zu streamen, müssen Sie 'Arrays.stream (myArray)' verwenden. Momentan ist Ihre Liste eine Liste von Arrays, keine Liste von Elementen aus den Arrays. – Andreas

Antwort

2

Karte jeweils Item seiner A[] Array. Dann, wenn Sie einen Strom von A[] nur flach map es jedes A von jedem Array zu bekommen und machen es ein Array am Ende.

A[] array = l.stream().map(x -> x.getParts()) 
         .flatMap(x -> Arrays.stream(x)) 
         .toArray(A[]::new); // [1, 2, 3, 4] 

Wenn Sie jedoch daran interessiert sind nur in den int Wert, gibt es einen zusätzlichen Schritt

int[] array = l.stream().map(x -> x.getParts()) 
         .flatMap(x -> Arrays.stream(x)) 
         .mapToInt(x -> x.getX()) 
         .toArray(); 
+2

Ich empfehle in dieser Situation 'Arrays.stream' anstelle von' Stream.of' zu verwenden. – Holger

+0

@Holger du bist völlig richtig! –

1

Sie möchten .flatMap() anstelle von .map() verwenden; im Lambda erzeugen Sie einfach einen neuen Strom der Elemente im Array.

1

Versuchen folgende:

static void test() { 
     List<Item> l = new ArrayList<>(); 
     l.add(new Item(1, 2,5)); 
     l.add(new Item(3, 4,10)); 

     System.out.println(l); 

     int totalNoOfParts = l.stream().mapToInt(item->item.getParts().length).reduce(0, Integer::sum); 

     A[] allParts = l.stream().map(item -> item.getParts()).collect(() -> new A[totalNoOfParts], 
       (c, e) -> System.arraycopy(e, 0, c, getNextPos(c), e.length), 
       (c1, c2) -> System.arraycopy(c2, 0, c1, getNextPos(c1), c2.length)); 

     System.out.println(Arrays.asList(allParts)); 

    } 

    static int getNextPos(A[] a) { 
     for (int i = 0; i < a.length; i++) { 
      if (a[i] == null) 
       return i; 
     } 
     throw new InvalidParameterException("Invalid index value"); 
    } 

ich Ihre Item-Klasse modifizierte feste Länge von Array zu haben.

class Item { 

    A[] parts = new A[3]; 

    Item(int... values) { 

     Objects.requireNonNull(values, "Argument Not Valid"); 

     for (int i = 0; i < values.length; i++) { 
      parts[i] = new A(); 
      parts[i].x = values[i]; 
     } 
    } 

    public A[] getParts() { 
     return parts; 
    } 
}