Nick Div
Nick Div

Reputation: 5628

How can I extract values from a list of objects based on a property of these objects?

I'd like to find objects in a list based on having a certain property.

For example, say I have a list of objects of this class:

class Person {
    private String name;
    private String id;
}

I know that I can get all of the names of people in the list by using:

Collection<String> names = CollectionUtils.collect(
    personList,
    TransformerUtils.invokerTransformer("getName"));  

but what I want to do is get a list of the Person objects whose name is, for example, "Nick". I don't have Java 8.

Upvotes: 2

Views: 15955

Answers (5)

Banns
Banns

Reputation: 596

I am considering that you might have a collection of different objects that have this property name. For that I would recommend you to do parent for those components and perform the search on it with generics:

For example:

Parent class Name.java

public class Name {

    private String name;

    public Name(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

Class Pet.java

public class Pet extends Name{

    public Pet(String name) {
        super(name);
    }

}

And class Person.java

public class Person extends Name{

    public Person(String name) {
        super(name);
    }

}

Job class that doesn't have the property:

public class Job {

    private String description;

    public Job(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

}

Having that, you can check the instance of it and compare what you want:

public static void main(String ... args) {
    List<Object> objectList = new ArrayList();
    objectList.add(new Person("Nick"));
    objectList.add(new Person("Nik"));
    objectList.add(new Person("Nikc"));
    objectList.add(new Person("Ncik"));
    objectList.add(new Pet("Nick"));
    objectList.add(new Pet("Nik"));
    objectList.add(new Pet("Nikc"));
    objectList.add(new Pet("Ncik"));
    objectList.add(new Job("Nick"));
    objectList.add(new Job("Nik"));
    objectList.add(new Job("Nikc"));
    objectList.add(new Job("Ncik"));

    for (Object o : extractObjectsMatching("Nick", objectList)){
        System.out.println(((Name) o).getName());
    }
}

public static List<Object> extractObjectsMatching(String name, List<Object> objectList){
    List<Object> matches = new ArrayList<>();
    for (Object e : objectList){
        if (e instanceof Name && ((Name) e).getName().contains(name)){
            matches.add(e);
        }
    }

    return matches;
}

If the Object class is not an instance of Name, means that will not have the property that you are looking for, just ignore, otherwise, compare with the information that you want and store to retrieve.

Upvotes: 0

user5859623
user5859623

Reputation:

You could try using a HashMap.

HashMap<String, Integer> points = new HashMap<String, Integer>();
    points.put("Amy", 154);
    points.put("Dave", 42);
    points.put("Rob", 733);
    System.out.println(points.get("Dave")); 

This would only be an example, but you could check and instead of having the String, Integer, you could try Integer, String and have an if statement. Just an idea though.

Upvotes: 0

BeeOnRope
BeeOnRope

Reputation: 64925

Using Apache collection utils (which you are already using), you can use the filter method which creates a subset of your collection consisting of items which match a given filter, combined with a Predicate that matches "Nick" based on your Transformer and transformedPredicate:

CollectionUtils.filter(names, PredicateUtils.transformedPredicate(
    TransformerUtils.invokerTransformer("getName"), PredicateUtils.equalPredicate("Nick")));

That said, you may want to reconsider using such a heavily functional approach before you migrate to Java 8. Not only will you have a lot of redundant Apache collections code after you migrate, the solutions prior to the introduction of closures and lambdas tend to be verbose and often less readable than the imperative alternatives.

Note: this modifies the existing collection in-place. If that is not the desired behavior, you'll need to create a copy before calling the filter method.

Upvotes: 3

SomeDude
SomeDude

Reputation: 14238

I see you are using Apache Common Utils, then you can use:

CollectionUtils.filter( personList, new Predicate<Person>() {
    @Override
    public boolean evaluate( Person p ) {
        return p.getName() != null && p.getName().equals( "Nick" );
    }
});

Upvotes: 6

TimoStaudinger
TimoStaudinger

Reputation: 42450

If you don't want to use Java 8 streams, simply loop through the list and check the elements manually:

ArrayList<Person> filteredList = new ArrayList<Person>();

for(Person person : personList) {
    if(person.getName().equals("Nick")) filteredList.add(person);
}

Upvotes: 3

Related Questions