39

オブジェクトのリストがあり、リストは非常に大きいです。オブジェクトは

class Sample {
    String value1;
    String value2;
    String value3;
    String value4;
    String value5;
 }

ここで、リスト内のオブジェクトの特定の値を検索する必要があります。それらのオブジェクトを返さなければならないかどうかvalue3=='three' (私の検索は常に value3 に基づいているわけではありません)

リストは

List<Sample> list = new ArrayList<Sample>();

それを行う効率的な方法は何ですか?

ありがとう。

4

7 に答える 7

56

Apache Commons Collectionsを試すことができます。

カスタムPredicateでアイテムを選択またはフィルタリングできるCollectionUtilsクラスがあります。

コードは次のようになります。

Predicate condition = new Predicate() {
   boolean evaluate(Object sample) {
        return ((Sample)sample).value3.equals("three");
   }
};
List result = CollectionUtils.select( list, condition );

アップデート:

java8では、Lambdas と StreamAPI を使用すると、のようになります。

List<Sample> result = list.stream()
     .filter(item -> item.value3.equals("three"))
     .collect(Collectors.toList());

ずっといい!

于 2012-10-30T13:31:53.577 に答える
47

Java 8 の使用

Java 8 では、リストをストリームに変換するだけで、次のように記述できます。

import java.util.List;
import java.util.stream.Collectors;

List<Sample> list = new ArrayList<Sample>();
List<Sample> result = list.stream()
    .filter(a -> Objects.equals(a.value3, "three"))
    .collect(Collectors.toList());

ご了承ください

  • a -> Objects.equals(a.value3, "three")ラムダ式です
  • resultタイプをList持つSample
  • それは非常に高速で、反復ごとにキャストする必要はありません
  • フィルター ロジックが重くなる場合は、list.parallelStream()代わりにlist.stream()( read this )を実行できます。


アパッチ・コモンズ

Java 8 を使用できない場合は、Apache Commonsライブラリを使用して次のように記述できます。

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;

Collection result = CollectionUtils.select(list, new Predicate() {
     public boolean evaluate(Object a) {
         return Objects.equals(((Sample) a).value3, "three");
     }
 });

// If you need the results as a typed array:
Sample[] resultTyped = (Sample[]) result.toArray(new Sample[result.size()]);

ご了承ください:

  • 各反復でからObjectへのキャストがありますSample
  • 結果を として入力する必要がある場合はSample[]、追加のコードが必要です (私のサンプルに示されているように)



おまけ:リスト内の要素を見つける方法について説明している素敵なブログ記事。

于 2014-09-06T18:52:02.633 に答える
4

常に に基づいて検索する場合value3は、オブジェクトを Map に保存できます。

Map<String, List<Sample>> map = new HashMap <>();

key = value3その後、同じvalue3プロパティを持つ Sample オブジェクトの value = list を使用してマップに入力できます。

次に、マップをクエリできます。

List<Sample> allSamplesWhereValue3IsDog = map.get("Dog");

注: 2 つのSampleインスタンスが同じ を持つことができないvalue3場合は、単純にMap<String, Sample>.

于 2012-10-30T12:31:34.683 に答える
3

このリストを変更し、サンプルにリストを追加しますこれを試してください

疑似コード

Sample {
   List<String> values;
   List<String> getList() {
   return values}
}



for(Sample s : list) {
   if(s.getString.getList.contains("three") {
      return s;
   }
}
于 2012-10-30T12:33:32.437 に答える
0

リストは であるためArrayList、ソートされていないと想定できます。したがって、 O(n)よりも高速な要素を検索する方法はありません。

可能であれば、サンプル クラスに固有のリストをSet(HashSet実装として)に変更することを検討する必要があります。Comparator

別の可能性は、を使用することHashMapです。データを次のように追加しSample(クラス名は大文字で始めてください)、検索する文字列をキーとして使用できます。次に、単に使用できます

Sample samp = myMap.get(myKey);

キーごとに複数のサンプルがある場合は を使用しMap<String, List<Sample>>、それ以外の場合は を使用しますMap<String, Sample>複数のキーを使用する場合、同じデータセットを保持する複数のマップを作成する必要があります。それらはすべて同じオブジェクトを指しているため、スペースはそれほど問題にはなりません。

于 2012-10-30T12:42:22.717 に答える
0

for+if はどうですか?

Object result; 
for (Object o: objects){ 
  if (o.value3.equals("three")){ 
    result=o; 
    break;
  }
}

ストリームもグアバもありません。シンプルだと思います。

于 2022-02-15T13:37:53.670 に答える