web-dev-qa-db-ja.com

チェックインする方法Java Setに文字列値を持つオブジェクトが含まれている場合?

オブジェクトのセットがあります。各オブジェクトには文字列値があります。

「direction」に等しいthis値を持つすべてのオブジェクトを選択する必要があります。

セットを繰り返すことなく可能ですか?

ありがとう。

19
user710818

一般的に、いいえ。セットを反復処理し、各オブジェクトをチェックして、プロパティが検索する値と等しいかどうかを確認する必要があります。これはO(n)操作です。

反復せずに実行できる状況が1つあります。オブジェクトのequalsメソッドがそのStringプロパティの等価性に関して定義されている場合、およびhashCodeメソッドも正しく実装されている場合、 _hashSet.contains_O(1) timeで正しい値を持つオブジェクトを見つけるには、セットを繰り返し処理する必要はありません。

前述したように、これは非常に具体的なユースケースであり、一般的なソリューションではありません。文字列が何らかの一意の識別子である場合は便利かもしれませんが、特定のユースケースでは機能しません。

また、ユースケースに適した他のコレクションを検討することもできます。たとえば、Guavaを使用している場合は、 Multimap の使用を検討できます。

関連

24
Mark Byers

はい、これはequals()メソッドを上書きするで可能です。

@Override 
public boolean  equals (Object object) {

}

Equalsメソッドですべてが機能することを確認したいだけです。

コード:

package com.webapp.test;

import Java.util.ArrayList;
import Java.util.List;

public class EmployeeModel {    

    public EmployeeModel(String name, String designation, long age) {
        this.name = name;
        this.designation = designation;
        this.age = age;
    }

    private String name;
    private String designation;
    private long age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public long getAge() {
        return age;
    }

    public void setAge(long age) {
        this.age = age;
    }

    @Override
    public boolean equals (Object object) {
        boolean result = false;
        if (object == null || object.getClass() != getClass()) {
            result = false;
        } else {
            EmployeeModel employee = (EmployeeModel) object;
            if (this.name == employee.getName() && this.designation == employee.getDesignation() && this.age.equals(employee.getAge())) {
                result = true;
            }
        }
        return result;
    }
}

public static void main(String args[]) {
    EmployeeModel first = new EmployeeModel("Sameer", "Developer", 25);
    EmployeeModel second = new EmployeeModel("Jon", "Manager", 30);
    EmployeeModel third = new EmployeeModel("Priyanka", "Tester", 24);

    List<EmployeeModel> employeeList = new ArrayList<EmployeeModel>();
    employeeList.add(first);
    employeeList.add(second);
    employeeList.add(third);

    EmployeeModel checkUserOne = new EmployeeModel("Sameer", "Developer", 25);
    System.out.println("Check checkUserOne is in list or not ");
    System.out.println("Is checkUserOne Present = ? " + employeeList.contains(checkUserOne));

    EmployeeModel checkUserTwo = new EmployeeModel("Tim", "Tester", 24);
    System.out.println("Check checkUserTwo is in list or not");
    System.out.println("Is checkUserTwo Present = ? " + employeeList.contains(checkUserTwo));

}

出力:

Check checkUserOne is in list or not 
Is checkUserOne Present = ? true
Check checkUserTwo is in list or not 
Is checkUserTwo Present = ? false
8
Sameer Kazi

この質問のようにPredicateを使用してリストをフィルタリングすることもできます。 Javaコレクション?

3

これは古い質問ですが、...

簡単な答え:いいえ、それは不可能です...

他のフェローが推奨するequals()またはcontains()の使用は、フィルタリングに使用している属性が実際にはオブジェクトIDの一部である状況に制限する必要があります。私は、O(n)アルゴリズム以外に方法はありません。

ネイティブ関数を検討している場合、Java 8はStream APIFunctional Programmingの概念をもたらし、より簡単でクリーンなループ呼び出しを可能にしました。状況によっては、コレクション内のすべてのオブジェクトをチェックする必要があるため、複雑さはO(n)のままになることに注意してください。

Java 8のstream().filter()を使用した例

public static void main(String[] args...){
    Set<MyClass> mySet = new HashSet<>();
    mySet.add(new MyClass("Obj 1", "Rio de Janeiro"));
    mySet.add(new MyClass("Obj 2", "London"));
    mySet.add(new MyClass("Obj 3", "New York"));
    mySet.add(new MyClass("Obj 4", "Rio de Janeiro"));

    Set<MyClass> filtered = mySet.stream()
                                 .filter(mc -> mc.getCity().equals('Rio de Janeiro'))
                                 .collect(Collectors.toSet());

    filtered.forEach(mc -> System.out.println("Object: "+mc.getName()));

    // Result:
    //    Object: Obj 1 
    //    Object: Obj 4 
}
2
Felipe Leão

contains()メソッドも使用できます。

最初のセットをマッピングして、オブジェクトのセットに存在するかどうかを確認したいフィールド値のみを含むストリングのセットに変換するだけです。

FelipeLeão および Michael Laffargue の以前の回答に基づいた次の例を参照してください。

public static void main(String[] args...){
     Set<MyClass> mySet = new HashSet<>();
     mySet.add(new MyClass("Obj 1"));
     mySet.add(new MyClass("Obj 2"));
     mySet.add(new MyClass("Obj 3"));

     Set<String> mapped = mySet.stream()
                             .map(MyClass::getField())
                             .collect(Collectors.toSet());

     mapped.contains("Obj 1");
     mapped.contains("Obj 2");
     mapped.contains("Obj 4");

     // Result:
     //     true 
     //     true
     //     false

}

0