12

I have a list of items, and I want to find a list of items that have the boolean property (field variable) x=true.

I know that this can be accomplished by iteration, but I was looking for a common method to do that in commons library like Apache Commons.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Mahmoud Saleh
  • 33,303
  • 119
  • 337
  • 498
  • possible duplicate of [Finding all objects that have a given property inside a collection](http://stackoverflow.com/questions/587404/finding-all-objects-that-have-a-given-property-inside-a-collection) – Ciro Santilli OurBigBook.com Mar 23 '15 at 16:41

5 Answers5

21

You could use apache commons collection implementing a Predicate for it.

http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html

Sample:

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

A few sample can be found here: http://apachecommonstipsandtricks.blogspot.de/2009/01/examples-of-functors-transformers.html

And if you need something more generic, like inspect a value of a specific field or property you could do something like:

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

}

That could compare a specific property to a expected value, and the use would be something like:

Collection filtered = CollectionUtils.select(users, new MyPredicate("name", "User Name 2"));
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
  • 1
    Does using CollectionsUtils.select return a brand new collection, or does this new collection contain references to the original collection . I have tried to use this by defining my own predicate, however both my collections are getting modified. – Rohan Mar 15 '16 at 10:09
11

The problem is that iteration in Java is often much simpler and cleaner. Perhaps Java 8's Closures will fix this. ;)

Compare with @Spaeth's solution.

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

As you can see it much shorter and more concise.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 3
    If you have hard coded predicates then is true. But when you need to extend the logic and provide various elements for logical expression that in the end give proper data set cleaner is some functional Idioms API as proposed Guava. – Damian Leszczyński - Vash Jun 11 '12 at 13:18
  • @Vash +1 This is true, but relatively rare. BTW: I use predicates in a library I wrote so I am not against them. – Peter Lawrey Jun 11 '12 at 13:30
5
List<Foo> result = foos.stream()
  .filter(el -> el.x == true)
  .collect(Collectors.toList());

https://www.mkyong.com/java8/java-8-streams-filter-examples/

BARJ
  • 1,543
  • 3
  • 20
  • 28
4

You can use Google guava's filter method to do this. Commons also has a filter method

Steve Chambers
  • 37,270
  • 24
  • 156
  • 208
Hari Menon
  • 33,649
  • 14
  • 85
  • 108
1

To achieve this In java, you can Override hashCode and equals methods -

for example

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

in this example i have mached eventId integer value. You can use your class and his property here. After this you can use list's contains,indexOf,lastIndexOf and get method to find element in the list. See below.

//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));
}
Ahamed
  • 39,245
  • 13
  • 40
  • 68
Pramod Kumar
  • 7,914
  • 5
  • 28
  • 37