Zuordnung über generische Sammlung in Java 11 [Duplikat]
Ich habe versucht, eine Möglichkeit zu finden, eine generische Funktion zu schreiben - möglicherweise ohne Generika -, um eine Sammlung abzubilden.
Angenommen, ich habe eine Funktion von A bis B. Ich möchte eine Funktion schreiben, die a nimmt Collection<A>
und a zurückgibt Collection<B>
. HINWEIS: A und B sind keine Generika, sondern nur eine Möglichkeit, ein allgemeines Muster auszudrücken.
Was ich bisher habe ist
public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toCollection(() -> points));
}
Ich erhalte jedoch einen Tippfehler in der .collect
, weil ich natürlich möchte, dass die neue Sammlung ist, Collection<Point>
aber ich bin nicht sicher, wie ich einen Lieferanten dafür bekommen kann?
Bearbeiten: Ich möchte diese Funktion generisch nutzen können: Wenn ich ein Set übergebe, bekomme ich ein Set zurück, aber wenn ich es als Liste übergebe, bekomme ich eine Liste zurück. ist das überhaupt möglich?
Antworten
Die beste Option ist, nicht zu kompliziert zu werden und einfach Folgendes zu tun:
public static Collection<Point> points2dToPoints(Collection<Point2D> points) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(Collectors.toList());
}
eine konkrete Implementierung der Schnittstelle Rückkehr Collection
( zB Collectors.toList()
) , während von außen die Details der Implementierung versteckt, ( dh mit Collection
in der Methodensignatur).
Sie können Ihre Methode jedoch allgemeiner gestalten, indem Sie ihr als Supplier
konkrete Implementierung der Schnittstelle übergeben Collection
, die sie zurückgeben soll, nämlich
public static Collection<Point> points2dToPoints(Collection<Point2D> points, Supplier<Collection<Point>> aNew) {
return points.stream()
.map(Utils::point2dToPoint)
.collect(toCollection(aNew));
Auf diese Weise können Sie die konkrete Collection
Implementierung übergeben, die zurückgegeben wird, zum Beispiel:
points2dToPoints(.., ArrayList::new);
points2dToPoints(.., TreeSet::new);
Ersetzen Sie die Anweisung Collectors.toCollection(() -> points)
durch Collectors.toList()
.
Demo:
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
class Car {
String name;
public Car(String name) {
this.name = name;
}
@Override
public String toString() {
return "Car [name=" + name + "]";
}
}
class Book {
Car car;
public Book(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
}
public class Main {
public static void main(String[] args) {
// Test
Collection<Car> list = points2dToPoints(
List.of(new Book(new Car("Toyota")), new Book(new Car("Ford")), new Book(new Car("Suzuki"))));
list.forEach(System.out::println);
}
public static Collection<Car> points2dToPoints(Collection<Book> points) {
return points.stream().map(Book::getCar).collect(Collectors.toList());
}
}
Ausgabe:
Car [name=Toyota]
Car [name=Ford]
Car [name=Suzuki]