web-dev-qa-db-ja.com

リストの各要素でメソッドを呼び出すにはどうすればよいですか?

車のリストがあると仮定します:

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());
}

上記のコードを短縮するにはどうすればよいですか?簡単に言えば、リストの各要素でメソッドを呼び出すにはどうすればよいですか?

たとえば、Python:

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

UPDATE:

Aaiezzaの answer を参照してください。Java 8ラムダ式を使用したソリューション。

オリジナルのJava 8以前の答え:

この効果はGuavaで実現できます。Function実装は既に持っているものよりも冗長です:

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);

(それを念頭に置いて - Lists.transform は、関数を遅延的に適用するビューを返します-すぐにコピーしたい場合は、返されたリストを新しいリストにコピーする必要があります。

したがって、これはコードを短縮するのに役立ちませんが、Javaで目的の効果を達成するための冗長性の例です。

Edit:探しているものに近づいているように見えるライブラリ lambdaj を見るかもしれません。私は自分でこれを試したことはありませんが、ホームページには次の例が示されています。

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

Java 8には(できれば)何らかの形式のラムダ式があり、これによりこのようなコードが実行可能になります。 (リストの内包表記のようなものがあるかどうかは別問題です。)

あなたの願いが叶いました!

---編集---
キューのように笑: forEach()

間違いなくこれをチェックしてください。

具体的には、次の質問になります。

// 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()) );

彼らがここでやったことは本当に素晴らしい。これが今後使用されるのを楽しみにしています。

---編集---
私はこれをもっと早く見るべきでしたが、抵抗することはできません。

Jdk8で追加されたストリーム機能は、 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() );

さらに簡潔なのは、Java 8の メソッド参照Oracle doc )を使用することです。

List<String> names = cars.stream().map( Car::getName ).collect( Collectors.toList() );
63
aaiezza

中かっこを削除したり、すべてのコードを1行に移動したりするのは良い考えではありませんが、できません。

2
hvgotcodes

Common-LISPにはmapcar-functionがあります(これは上記のcar-exampleとは関係ありません)。 Javaの一般的なmapcar関数:

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());
}

車の例:

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

立ち往生していて、まだApache Commonsを使用する必要がある場合は、Transformerクラスが役立ちます。 http://apachecommonstipsandtricks.blogspot.de/2009/01/examples-of-functors-transformers.html

0
Marek Puchalski