Java 使用番石榴基于一个属性筛选列表

Java 使用番石榴基于一个属性筛选列表,java,guava,Java,Guava,我有一门课叫Person- public class Person implements Nameable { private String name; public String getName(){ return name; } } 现在我有两份清单- List<Person> persons = // some persons List<Person> subsetOfPersons = // some duplicat

我有一门课叫Person-

public class Person implements Nameable {
    private String name;

    public String getName(){
        return name;
    }
}
现在我有两份清单-

List<Person>  persons = // some persons
List<Person> subsetOfPersons = // some duplicate persons, but different objects and don't share the same identity
List persons=//一些人
List subsetOfPersons=//一些重复的人,但是不同的对象和不共享相同的身份
现在,我想过滤
人员
子部分中不存在的
人员
,相等条件是name属性,并且人员没有相等项


我该怎么做

似乎您必须手动迭代这两个列表(听起来很蹩脚,但这是我唯一能想到的)


我相信有一个更简单的方法。。。为了便于比较,下面将把person转换为name。对于
子类人员
,我们实际上直接创建了一个姓名列表,因为这是我们真正需要的。对于
,我们将转换限制在比较的上下文中

    Iterable<Person> filtered = Iterables
            .filter(
                persons, 
                Predicates.not(
                    Predicates.compose(
                        Predicates.in(ImmutableSet.copyOf(Iterables.transform(subsetOfPersons, personToNamefunction))),
                        personToNamefunction
                    )
                )
            );
Iterable filtered=Iterables
.过滤器(
人,
谓词不是(
谓词.compose(
Predicates.in(ImmutableSet.copyOf(Iterables.transform(subsetOfPersons,personToNamefunction)),
人名函数
)
)
);
编辑:我想你可能会喜欢JUnit:

package com.stackoverflow.test;

import static org.junit.Assert.*;

import java.util.Iterator;

import org.junit.Test;

import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

public class PersonTest {
    public class Person {
        private String name;

        public String getName(){
            return name;
        }

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

    @Test
    public void testNameBasedFiltering() {
        Person bob = createPerson("bob");
        Person jim = createPerson("jim");
        Person pam = createPerson("pam");
        Person roy = createPerson("roy");

        ImmutableList<Person> persons = ImmutableList.of(
                bob,
                jim,
                pam,
                roy); 
        ImmutableList<Person> subsetOfPersons = ImmutableList.of(
                createPerson("jim"),
                createPerson("pam"));

        Function<Person, String> personToNamefunction = new Function<Person, String>() {
            public String apply(Person arg0) {
                return arg0.getName();
            }
        };

        Iterable<Person> filtered = Iterables
                .filter(
                    persons, 
                    Predicates.not(
                        Predicates.compose(
                            Predicates.in(ImmutableSet.copyOf(Iterables.transform(subsetOfPersons, personToNamefunction))),
                            personToNamefunction
                        )
                    )
                );

        for (Person person : filtered) {
            assertNotSame(jim, person);
            assertNotSame(pam, person);         
        }
    }

    public Person createPerson(String name) {
        Person person = new Person();
        person.setName(name);

        return person;
    }

}
package com.stackoverflow.test;
导入静态org.junit.Assert.*;
导入java.util.Iterator;
导入org.junit.Test;
导入com.google.common.base.Function;
导入com.google.common.base.谓词;
导入com.google.common.collect.ImmutableList;
导入com.google.common.collect.ImmutableSet;
导入com.google.common.collect.Iterables;
公共类个人测试{
公共阶层人士{
私有字符串名称;
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
}
@试验
public void testNameBasedFiltering(){
人员bob=createPerson(“bob”);
人员jim=创建人员(“jim”);
人员pam=createPerson(“pam”);
人罗伊=创造者罗伊;
ImmutableList persons=ImmutableList.of(
上下快速移动
吉姆,
潘,
罗伊);
ImmutableList subsetOfPersons=ImmutableList.of(
createPerson(“吉姆”),
创建人(“pam”);
函数personToNamefunction=新函数(){
公共字符串应用(人员arg0){
返回arg0.getName();
}
};
Iterable过滤=Iterables
.过滤器(
人,
谓词不是(
谓词.compose(
Predicates.in(ImmutableSet.copyOf(Iterables.transform(subsetOfPersons,personToNamefunction)),
人名函数
)
)
);
for(个人:已筛选){
资产不相同(吉姆,个人);
资产不相同(pam,个人);
}
}
公众人物createPerson(字符串名称){
Person=新人();
person.setName(name);
返回人;
}
}

再次编辑:第一次错过了“不”要求。轻松修复——使用谓词,您可以使用
谓词包装。而不是(…)

忽略我的回答,上面的比我的好。我仍然会把这个放在这里,以展示优秀和糟糕程序员之间的区别……甚至没有想到谓词。编写,很好!我想他不想(在(名字集))谢谢你的邀请。用not包装谓词,并更新JUnit以反映更改。仅供参考——有一些Guava增强请求(,)可以使此代码更简单,并消除转换列表的需要。kevinb拒绝添加对等价性的支持,基于编写等价实现的机会,这些实现会导致集合不遵守其契约。
package com.stackoverflow.test;

import static org.junit.Assert.*;

import java.util.Iterator;

import org.junit.Test;

import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

public class PersonTest {
    public class Person {
        private String name;

        public String getName(){
            return name;
        }

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

    @Test
    public void testNameBasedFiltering() {
        Person bob = createPerson("bob");
        Person jim = createPerson("jim");
        Person pam = createPerson("pam");
        Person roy = createPerson("roy");

        ImmutableList<Person> persons = ImmutableList.of(
                bob,
                jim,
                pam,
                roy); 
        ImmutableList<Person> subsetOfPersons = ImmutableList.of(
                createPerson("jim"),
                createPerson("pam"));

        Function<Person, String> personToNamefunction = new Function<Person, String>() {
            public String apply(Person arg0) {
                return arg0.getName();
            }
        };

        Iterable<Person> filtered = Iterables
                .filter(
                    persons, 
                    Predicates.not(
                        Predicates.compose(
                            Predicates.in(ImmutableSet.copyOf(Iterables.transform(subsetOfPersons, personToNamefunction))),
                            personToNamefunction
                        )
                    )
                );

        for (Person person : filtered) {
            assertNotSame(jim, person);
            assertNotSame(pam, person);         
        }
    }

    public Person createPerson(String name) {
        Person person = new Person();
        person.setName(name);

        return person;
    }

}