Как проверить java, если Set содержит объект с некоторым строковым значением?

У меня есть набор объектов. Каждый объект имеет значение String.

Мне нужно выбрать все объекты со значением this, равным "direction".

Можно ли без итерации по множеству?

Спасибо.

Ответ 1

В общем, нет. Вам нужно выполнить итерацию по набору и проверить каждый объект, чтобы узнать, соответствует ли свойство значению, которое вы ищете. Это операция O(n).

Есть одна ситуация, в которой вы могли бы сделать это без повторения. Если ваш объект equals метод определен в терминах равенства этого свойства String, и если метод hashCode также реализован правильно, вы можете использовать hashSet.contains, чтобы найти объект с правильным значением в O(1), не требуя повторения по набору.

Как я уже упоминал, это очень конкретный вариант использования, а не общее решение. Может быть полезно, если строка была своего рода уникальным идентификатором, но она не будет работать для вашего конкретного случая использования.

Вы также можете рассмотреть другие коллекции, которые лучше подходят для вашего использования. Например, если вы используете Guava, вы можете использовать Multimap.

Похожие

Ответ 2

Да, это возможно с помощью перезаписи метода equals. LIKE

 @Override 
public boolean  equals (Object object) {

}

Вы просто хотите перезаписать и определить все, что вы хотите проверить, равным параметру

Я приводил здесь свой рабочий пример.


пакет com.webapp.test;

import java.util.ArrayList;
import java.util.List

  public class EmployeeModel {  

    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;
}

public EmployeeModel(String name, String designation, long age) {
    this.name = name;
    this.designation = designation;
    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 Preasent = ? "+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 Preasent = ? "+employeeList.contains(checkUserTwo));

}

}


И результат будет выглядеть следующим образом

Проверить checkUserOne в списке или нет

Является checkUserOne Preasent =? True

Проверить checkUserTwo в списке или нет

Является checkUserTwo Preasent =? ложь

Ответ 4

Я знаю, что это старый вопрос, но...

Короткий ответ: НЕТ, это невозможно...

Использование equals() или contains(), как рекомендовано другими ребятами, должно быть ограничено ситуациями, в которых атрибуты, которые вы используете для фильтрации, на самом деле являются частью объектов Identity. Я не вижу никакого способа, кроме алгоритма O (n).

Если вы рассматриваете собственные функции, Java 8 принес Stream API и понятия Функциональное программирование, что позволяет упростить и очистить вызовы цикла. Тем не менее, стоит отметить, что для вашей ситуации все объекты в вашей коллекции должны быть проверены, поэтому сложность останется 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 
}