Как найти элементы в коллекции по свойству?
У меня есть список элементов, и я хочу найти список элементов с булевым свойством x=true
.
Я знаю, что это может быть выполнено путем итерации, но я искал общий метод для этого в общей библиотеке, например Apache Commons.
Ответы
Ответ 1
Проблема в том, что итерация в Java часто намного проще и чище. Возможно, Java 8 Closures исправит это.;)
Сравните с решением @Spaeth.
List<String> mixedup = Arrays.asList("A", "0", "B", "C", "1", "D", "F", "3");
List<String> numbersOnlyList = new ArrayList<>();
for (String s : mixedup) {
try {
// here you could evaluate you property or field
Integer.valueOf(s);
numbersOnlyList.add(s);
} catch (NumberFormatException ignored) {
}
}
System.out.println("Results of the iterated List: " + numbersOnlyList);
Как вы можете видеть, это намного короче и кратким.
Ответ 2
Вы можете использовать коллекцию apache commons, реализующую для нее предикат.
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html
Пример:
package snippet;
import java.util.Arrays;
import java.util.Collection;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
public class TestCollection {
public static class User {
private String name;
public User(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [name=" + name + "]";
}
}
public static void main(String[] args) {
Collection<User> users = Arrays.asList(new User("User Name 1"), new User("User Name 2"), new User("Another User"));
Predicate predicate = new Predicate() {
public boolean evaluate(Object object) {
return ((User) object).getName().startsWith("User");
}
};
Collection filtered = CollectionUtils.select(users, predicate);
System.out.println(filtered);
}
}
Несколько примеров можно найти здесь:
http://apachecommonstipsandtricks.blogspot.de/2009/01/examples-of-functors-transformers.html
И если вам нужно что-то более общее, например, проверить значение определенного поля или свойства, вы можете сделать что-то вроде:
public static class MyPredicate implements Predicate {
private Object expected;
private String propertyName;
public MyPredicate(String propertyName, Object expected) {
super();
this.propertyName = propertyName;
this.expected = expected;
}
public boolean evaluate(Object object) {
try {
return expected.equals(PropertyUtils.getProperty(object, propertyName));
} catch (Exception e) {
return false;
}
}
}
Это может сравнить конкретное свойство с ожидаемым значением, и использование будет выглядеть примерно так:
Collection filtered = CollectionUtils.select(users, new MyPredicate("name", "User Name 2"));
Ответ 3
Вы можете использовать Google guava filter
метод для этого. Commons также имеет filter
метод
Ответ 4
List<Foo> result = foos.stream()
.filter(el -> el.x == true)
.collect(Collectors.toList());
https://www.mkyong.com/java8/java-8-streams-filter-examples/
Ответ 5
Для этого в java вы можете переопределить методы hashCode и equals -
например
@Override
public int hashCode() {
return eventId;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof CompanyTimelineView) {
CompanyTimelineView new_name = (CompanyTimelineView) obj;
if(new_name.eventId.intValue() == this.eventId.intValue()){
return true;
}
}
return false;
}
в этом примере у меня есть искомое целое значение eventId. Вы можете использовать свой класс и его собственность здесь.
После этого вы можете использовать список содержит, indexOf, lastIndexOf и получить метод, чтобы найти элемент в списке. См. Ниже.
//tempObj is nothing but an empty object containing the essential properties
//tempObj should posses all the properties that are being compared in equals method.
if(listOfObj.contains(tempObj)){
return listOfObj.get(listOfObj.indexOf(tempObj));
}