オブジェクトのセットがあります。各オブジェクトには文字列値があります。
「direction」に等しいthis
値を持つすべてのオブジェクトを選択する必要があります。
セットを繰り返すことなく可能ですか?
ありがとう。
一般的に、いいえ。セットを反復処理し、各オブジェクトをチェックして、プロパティが検索する値と等しいかどうかを確認する必要があります。これはO(n)
操作です。
反復せずに実行できる状況が1つあります。オブジェクトのequals
メソッドがそのString
プロパティの等価性に関して定義されている場合、およびhashCode
メソッドも正しく実装されている場合、 _hashSet.contains
_O(1)
timeで正しい値を持つオブジェクトを見つけるには、セットを繰り返し処理する必要はありません。
前述したように、これは非常に具体的なユースケースであり、一般的なソリューションではありません。文字列が何らかの一意の識別子である場合は便利かもしれませんが、特定のユースケースでは機能しません。
また、ユースケースに適した他のコレクションを検討することもできます。たとえば、Guavaを使用している場合は、 Multimap の使用を検討できます。
関連
はい、これは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
この質問のようにPredicate
を使用してリストをフィルタリングすることもできます。 Javaコレクション?
これは古い質問ですが、...
他のフェローが推奨するequals()
またはcontains()
の使用は、フィルタリングに使用している属性が実際にはオブジェクトIDの一部である状況に制限する必要があります。私は、O(n)アルゴリズム以外に方法はありません。
ネイティブ関数を検討している場合、Java 8はStream APIとFunctional Programmingの概念をもたらし、より簡単でクリーンなループ呼び出しを可能にしました。状況によっては、コレクション内のすべてのオブジェクトをチェックする必要があるため、複雑さはO(n)のままになることに注意してください。
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
}
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
}