web-dev-qa-db-ja.com

Javaで配列をフィルタリングする方法は?

Javaで配列をフィルタリングするにはどうすればよいですか?

車などのオブジェクトの配列があります。

クラス:

public class Car{
    public int doors;
    public Car(int d){
        this.doors = d;
    }
}

使用する:

Car [] cars = new Cars[4];
cars[0] = new Car(3);
cars[1] = new Car(2);
cars[2] = new Car(4);
cars[3] = new Car(6);

次に、ドアを4つ以上残して、車の配列をフィルタリングします。

for(int i = 0; i<cars.length; i++){
    if(cars[i].doors > 4)
         //add cars[i] to a new array
    }
}

どうすればよいですか?

ベクターでやる前に:

Vector subset = new Vector();
for(int i = 0; i<cars.length; i++){
    if(cars[i].doors > 4)
         //add cars[i] to a new array
        subset.addElement(cars[i]);
    }
}

次に、Vectorのサイズで新しい配列を作成します。次に、ベクトルをもう一度ループして、新しい配列を埋めます。私はこれが単純な何かのための非常に大きな手順であることを知っています。

私はJ2MEを使用しています。

18
hsmit

EDIT:は、ArrayListがJ2MEにないことを確認しましたが、ドキュメントに基づくと、Vectorがあります。そのVectorクラスがJ2SEVectorと異なる場合( このドキュメントが示すように )、おそらく次のコードが機能します。

Vector carList = new Vector();
for(int i = 0; i<cars.length; i++){
    if(cars[i].doors > 4)
         carList.addElement(cars[i]);
    }
}
Car[] carArray = new Car[carList.size()];
carList.copyInto(carArray);
12
Kaleb Brasee

これを行う最も効率的な方法は、フィルタリングしている述語が安価で、単一のスレッドでアクセスしている場合、通常、リストを2回トラバースすることです。

public Car[] getFourDoors(Car[] all_cars) {
  int n = 0;
  for (Car c : all_cars) if (c.doorCount()==4) n++;
  Car[] cars_4d = new Car[n];
  n = 0;
  for (Car c : all_cars) if (c.doorCount()==4) cars_4d[n++] = c;
  return cars_4d;
}

これはリストを2回トラバースし、テストを2回呼び出しますが、追加の割り当てやコピーはありません。 Vectorスタイルのメソッドは、リストを1回トラバースしますが、必要なメモリの約2倍を(一時的に)割り当て、すべての適切な要素を約2回コピーします。したがって、リストのごく一部をフィルタリングしている場合(または、パフォーマンスが問題ではない場合、ほとんどの場合問題ではありません)、Vectorメソッドが適しています。それ以外の場合は、上記のバージョンの方がパフォーマンスが向上します。

5
Rex Kerr

結果として本当に単純な配列が必要な場合は、あなたのやり方が道だと思います。フィルタリングする前に結果の要素の数がわからず、要素の数がわからないと新しい配列を作成できません。 。

ただし、スレッドセーフが必要ない場合は、ArrayListの代わりにVectorを使用することを検討してください。やや速いはずです。次に、ArrayListのtoArrayメソッドを使用して配列を取得します。

2
Joonas Pulakka

System.arrayCopy()を使用できます:

Car[] cars = ...
int length = cars.length < 4 ? cars.length() : 4;
Car filter = new Car[4];
System.arrayCopy(cars, 0, filter, 0, length);

更新:System.arrayCopyは、Vector.subList()とは異なり、 Java ME API で使用できます。訂正していただきありがとうございます。

1
notnoop

私はあなたのコードに多くの間違いを見ることができません。ただし、全体を通してベクターを使用することもできます。

Vector.copyInto(Object [])を使用して、2番目の部分(一致するアイテムを新しい配列にコピーする)を簡略化できます。

1
finnw

配列から要素を削除する直接的な方法はありません。そのサイズは固定されています。何をするにしても、どういうわけか新しい配列を割り当てる必要があります。

Vectorを割り当てることによるわずかなメモリオーバーヘッドを回避したい場合、別のオプションは、配列を2回パスすることです。初めて、保持したい要素の数を数えるだけです。次に、そのサイズの配列を割り当て、古い配列を再度ループして、一致する要素を新しい配列にコピーします。

1
Porculus

とにかく、新しい配列を作成する必要があります。

Vector vector = new Vector(array.length);

for (int i = 0; i < array.length; i++) {
    if (array[i].doors > 4) {
        vector.add(array[i]);
    }
}

Car[] result = new Car[vector.size()];
vector.copyInto(result);

ただし、これはあまり効率的ではありません。

1
Bozho