如何在Java 8中使用流过滤两个列表对象并将值设置为新列表

tru*_*n92 4 java collections foreach java-8 java-stream

我使用Java 8,并且我有两个对象看起来像:

人类:

public class Person {

    private String id;
    private String name;

    public Person() {
    }

    public Person(String id, String name) {
        this.id = id;
        this.name = name;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
Run Code Online (Sandbox Code Playgroud)

Person1类别:

public class Person1 {
    private String id;
    private String name;

    public Person1() {
    }

    public Person1(String id, String name) {
        this.id = id;
        this.name = name;
    }

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

    @Override
    public String toString() {
        return "Person1{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
Run Code Online (Sandbox Code Playgroud)

我有两个列表看起来像:

 List<Person> persons= Arrays.asList(new Person("1","A"),new Person("2","B"));
  List<Person1> persons1 = Arrays.asList(new Person1("3","C"),new Person1("1","F"));
Run Code Online (Sandbox Code Playgroud)

现在我想使用流java 8循环两个列表并进行比较。如果列表人员中的任何对象等于person1,我将创建新列表并将其设置为新值。示例:如果Person1(“ 1”,“ F”)等于Person(“ 1”,“ A”),因为我使用id对其进行比较,那么我将从Person1的名称设置为Person。结果:Person(“ 1,” F“)并添加两个新列表。

我在使用以下代码时:

 for (Person person : persons) {
            for (Person1 person1 : persons1 ) {
                if (person1.getId().equals(person.getId())) {
                    person.setName(person1.getId());
                    break;
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

现在我想将其转换为具有新列表的流,如下所示:

 List<Person> personList =
                list.stream()
                        .filter (
                                person -> list1.stream()
                                        .anyMatch(person1 -> person1.getId()== person.getId()))
                        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但是它只过滤人。我想比较两个列表对象。如果具有相同的ID,我想将名称从person1中的对象设置为person。我知道我们可以在流java 8中使用map,但是我不能做到这一点。请帮忙

Rav*_*ala 6

有些任务最好用流完成,而另一些则需要迭代。结合两种方法可以最好地完成许多任务。在此解决方案中,使用流来构造地图,然后使用迭代来更新匹配人员的姓名。您的解决方案以二次时间运行,而此解决方案以线性时间复杂度运行。

Map<String, String> idToNameMap = persons1.stream()
    .collect(Collectors.toMap(Person1::getId, Person1::getName, (a, b) -> a));
for (Person person : persons) {
    if (idToNameMap.containsKey(person.getId())) {
        person.setName(idToNameMap.get(person.getId()));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 可以使用idToNameMap.containsKey(p.getId())代替`idToNameMap.get(p.getId())!= null`。但是,构造新的“ Person”实例与修改现有对象并不相同。 (2认同)
  • 好吧,这种矛盾是任务固有的。如果您假设对象是不可变的,则也不需要构造新对象,因为“ persons1”中的对象已经具有所需的属性,只需要过滤即可。 (2认同)