it-swarm.com.de

Wie kann ich eine Methode für jedes Element einer Liste aufrufen?

Angenommen, ich habe eine Liste von Autos:

public class Car {
    private String brand;
    private String name;
    private String color;

    public Car() { // ...  }

    public getName() { return name; }
    // ...
}

// Suppose that I have already init the list of car
List<Car> cars = //...
List<String> names = new ArrayList<String>();


for (Car c : cars ) {
    names.add(c.getName());
}

Wie kann ich den Code oben abkürzen? Kurz gesagt: Wie kann ich eine Methode für jedes Element einer Liste aufrufen?

Zum Beispiel in Python:

[car.name for car in cars]
32
Sandro Munda

UPDATE:

Siehe aaiezzas answer für eine Java 8-Lösung mit einem Lambda-Ausdruck.

Ursprüngliche Antwort vor Java 8:

Der Effekt kann mit Guava erreicht werden, die Function-Implementierung ist bereits ausführlicher als die, die Sie haben:

List<Car> cars = //...

Function<Car, String> carsToNames = new Function<Car, String>() {
   @Override
   public String apply(Car car) {
      return car.getName();
   }
}

List<String> names = Lists.transform(cars, carsToNames);

(Denken Sie daran, dass Lists.transform eine Ansicht zurückgibt, in der die Funktion träge angewendet wird - wenn Sie eine sofortige Kopie wünschen, müssen Sie die zurückgegebene Liste in eine neue Liste kopieren.)

Das hilft Ihnen also nicht, Ihren Code zu verkürzen, sondern ist ein Beispiel dafür, wie ausführlich es ist, den gewünschten Effekt in Java zu erzielen.

Edit: Vielleicht sehen Sie sich die Bibliothek lambdaj an, die sich anscheinend Ihren Wünschen annähert. Ich habe es nicht selbst ausprobiert, aber die Homepage zeigt dieses Beispiel:

List<Person> personInFamily = asList(new Person("Domenico"), new Person("Mario"), new Person("Irma"));
forEach(personInFamily).setLastName("Fusco");
20
Paul Bellora

Java 8 wird (hoffentlich) eine Form von Lambda-Ausdrücken haben, die Code wie diesen besser möglich machen. (Ob es so etwas wie Listenverständnisse gibt, ist eine andere Sache.)

Dein Wunsch wurde erfüllt!

---BEARBEITEN---
lol wie auf cue: forEach ()

Überprüfen Sie dies auf jeden Fall.

Speziell für Ihre Frage wird es folgendes:

// Suppose that I have already init the list of car
List<Car> cars = //...
List<String> names = new ArrayList<String>();

// LAMBDA EXPRESSION
cars.forEach( (car) -> names.add(car.getName()) );

Es ist wirklich unglaublich, was sie hier gemacht haben. Ich freue mich darauf, dass dies in Zukunft verwendet wird.

---BEARBEITEN---
Ich hätte das früher sehen sollen, aber ich kann nicht widerstehen, aber darüber zu posten.

Die in jdk8 hinzugefügte Stream-Funktionalität ermöglicht die Methode map .

// Suppose that I have already init the list of car
List<Car> cars = //...

// LAMBDA EXPRESSION
List<String> names = cars.stream().map( car -> car.getName() ).collect( Collectors.toList() );
56
aaiezza

abgesehen von dem Entfernen der Klammern und/oder dem Verschieben des gesamten Codes in eine Zeile, was möglicherweise keine gute Idee ist, können Sie nicht. 

2
hvgotcodes

In common-LISP gibt es eine Mapcar-Funktion (dies hat nichts mit dem obigen Auto-Beispiel zu tun) ..__ Eine allgemeine Mapcar-Funktion in Java:

static <LIST_TYPE, ELEM_TYPE> List<LIST_TYPE> mapcar(Collection<ELEM_TYPE> list, Function<ELEM_TYPE, LIST_TYPE> function)
{
    return list.stream().map(function).collect(Collectors.toList());
}

Für das Auto-Beispiel:

List<String> carNames = mapcar(cars, car -> car.getName());
0
Ben Janus

Wenn Sie stecken bleiben und Apache Commons verwenden müssen, kann die Transformer-Klasse hilfreich sein: http://apachecommonstipsandtricks.blogspot.de/2009/01/examples-of-functors-transformers.html

0
Marek Puchalski