2016-05-14 3 views
3

Ich versuche eine generische Klasse zu schreiben, die standardmäßig eine Sammlung zurückgibt, aber wenn der Aufruf von function einen speziellen Typ say List oder Set erfordert, sollte die Methode dazu in der Lage sein gib es. Ist das in Java möglich? Korrigiere mich, wenn ich es nicht richtig mache.Zurückkehrender generischer Typ, der eine spezifische Sammlung basierend auf dem an Parameter übergebenen Typ ist

public <U extends Collection> U saveOrUpdate(Iterable<T> entities, Class<U> klass) { 
    Iterable<T> savedEntities = this.repository.save(entities); 
    Type type = klass.getClass().getGenericSuperclass(); 
    ParameterizedType pt = (ParameterizedType) type; 
    if (pt.getTypeName().equalsIgnoreCase(Set.class.getName())) { 
     return StreamSupport.stream(savedEntities.spliterator(), false) 
       .collect(Collectors.toSet()); 
    } else if (pt.getTypeName().equalsIgnoreCase(List.class.getName())) { 
     return StreamSupport.stream(savedEntities.spliterator(), false) 
       .collect(Collectors.toList()); 
    } else { 
     return StreamSupport.stream(savedEntities.spliterator(), false) 
       .collect(Collectors.toCollection()); 
    } 
} 
+1

Warum versuchst du es nicht einfach? Oder noch besser, machen Sie es zu einem eigenständigen Beispiel und kompilieren Sie es. 'Collectors.toCollection()' erwartet ein 'Supplier'-Argument, BTW. – stholzm

+0

Ich habe versucht, aber Compiler gibt Fehler auf bestimmten Collectors.toSet() und Collectors.toList() Collectors.toList() –

Antwort

4

Ich glaube nicht, gibt es eine typsichere Lösung mit Ihrem Ansatz - Sie könnte warf die zurück Sammlung U, ich denke ...

Statt die Class zugeben, wouldn‘ t es einfacher sein, wenn Sie die Supplier für Collectors#toCollection übergeben?

public <U extends Collection<T>> U saveOrUpdate(Iterable<T> entities, Supplier<U> supplier) { 
    Iterable<T> savedEntities = this.repository.save(entities); 
    return StreamSupport.stream(savedEntities.spliterator(), false) 
         .collect(Collectors.toCollection(supplier)); 
} 

Dann würden Sie die volle Kontrolle über den Ergebnistyp haben, z.B .:

saveOrUpdate(entities, HashSet::new); // constructor as Supplier 

Und es gibt Kontrollen sogar.

+0

Dank Mann, du bist ein Lebensretter. –

Verwandte Themen