web-dev-qa-db-ja.com

Javaオブジェクトのリストで検索する方法

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

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

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

リストは

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

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

ありがとう。

25
Jeevi

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

クラス CollectionUtils があり、カスタム Predicate で項目を選択またはフィルタリングできます。

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

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

ずっといい!

41
Esteve

Java 8を使用

Java 8 を使用すると、リストを stream に変換するだけで、次のように記述できます。

_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")ラムダ式
  • resultListタイプのSampleです
  • 非常に高速で、繰り返しごとにキャストしません
  • フィルタロジックが重くなった場合は、list.parallelStream()の代わりにlist.stream()を実行できます( read this


Apache Commons

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[]_と入力する必要がある場合は、追加のコードが必要です(私のサンプルに示すように)



ボーナス: 素敵なブログ記事 リスト内の要素を見つける方法について話します。

39
Yves M.

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

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

その後、マップにkey = value3およびvalue =同じ同じvalue3プロパティを持つサンプルオブジェクトのリストを入力できます。

その後、マップを照会できます。

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

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

3
assylias

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

擬似コード

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



for(Sample s : list) {
   if(s.getString.getList.contains("three") {
      return s;
   }
}
3
MemLeak

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

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

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

Sample samp = myMap.get(myKey);

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

0
brimborium