获得满足条件的第一个对象

时间:2015-03-15 20:01:30

标签: java guava

我在下载符合条件的列表中的第一个对象时遇到问题。

我的代码总是返回列表中的第一个对象,无论条件如何。返回id = 1的人。

main(){
   public static void main(String args[]) {
    List<Person> persons = Lists.newArrayList();
    persons.add(new Person("1", "aaa",23, true));
    persons.add(new Person("2", "bbb",16, false));
    persons.add(new Person("3", "ccc",56, true));


    Person per = (Person) Iterables.getFirst(persons, new Predicate<Person>() {
        @Override
        public boolean apply(Person person) {
            return person.getAge()> 50;
        }
    });

    System.out.println(per.getId());  // always "1"
}


public class Person {
    private String id;
    private String name;
    private int age;
    private boolean isSome;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isSome() {
        return isSome;
    }

    public void setSome(boolean isPaid) {
        this.isSome = isPaid;
    }
    public Person(){}

    public Person(String id, String name, int age, boolean isSome){
        this.id = id;
        this.name = name;
        this.age = age;
        this.isSome = isSome;
    }
}

有人可以解释为什么会这样,以及如何处理它?<​​/ p>

3 个答案:

答案 0 :(得分:8)

Iterables.getFirst()并不能按照您的想法行事。您应该使用Iterables.tryFind()方法,该方法返回传递的iterable中的第一个匹配元素。它返回Optional<T>,因此您需要在结果上调用get(),或者Optional#or(),如果您想要一些默认值。

Person per = Iterables.tryFind(persons, new Predicate<Person>() {
        @Override
        public boolean apply(Person person) {
            return person.getAge()> 50;
        }
    }).or(defaultPerson);

答案 1 :(得分:2)

Iterables.getFirst返回第一个参数的第一个元素,例如人的第一要素。第二个参数是persons为空的默认值。您可以改为使用filter

Person person = Iterables.getFirst(Iterables.filter(persons, new Predicate<Person>() {
    @Override
    public boolean apply(Person person) {
        return person.getAge() > 50;
    }
}), null);

答案 2 :(得分:2)

虽然您尝试使用guava解决此问题,但您可能对如何在java8中完成此操作感兴趣:

    List<Person> persons = Lists.newArrayList();
    persons.add(new Person("1", "aaa",23, true));
    persons.add(new Person("2", "bbb",16, false));
    persons.add(new Person("3", "ccc",56, true));

    Person per = persons.stream().filter(p -> p.getAge() > 50).findFirst().get();

    System.out.println(per.getId());

为了简洁起见,findFirst将返回Optional<Person>我打电话给它,但请注意,如果与getAge > 50的谓词不匹配,则get将返回null