3

I using java 8 and i have two object look like :

Person class :

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 + '\'' +
                '}';
    }
}

Person1 Class :

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 + '\'' +
                '}';
    }
}

I have two list look like :

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

Now i want using stream java 8 loop two list and compare. If any object in list persons equal with persons1 , i will create new list and set it with new value. Example : If Person1("1","F") equal Person("1","A") because i using id compare it, i get name from Person1 set to Person. Result : Person("1,"F") and add it two new list.

My code when i using for:

 for (Person person : persons) {
            for (Person1 person1 : persons1 ) {
                if (person1.getId().equals(person.getId())) {
                    person.setName(person1.getId());
                    break;
                }
            }
        }

Now i want convert it to Stream with new list look like :

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

But it only filter person. I want compare two list object. If same id, i want set name from object in persons1 to persons. I know we can using map in stream java 8 but i can't how to do that. Please help

1
  • Why you want to use a break; here? Commented Jul 11, 2019 at 16:39

2 Answers 2

5

Some tasks are best accomplished with streams, and others with iteration. Many tasks are best accomplished by combining the two approaches. In this solution streams are used to construct the map and then iteration is used to update matching person's name. Your solution runs in Quadratic time whereas this solution runs in linear time complexity.

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()));
    }
}
Sign up to request clarification or add additional context in comments.

10 Comments

Instead of idToNameMap.get(p.getId()) != null, you can use idToNameMap.containsKey(p.getId()). But constructing new Person instances is not the same as modifying existing objects.
Thanks for the suggestion. I have updated the answer. Also I did not update the existing object since it contradicts with immutability in functional programming.
Well, that contradiction is inherent to the task. If you assume immutable objects, there wouldn’t be a need to construct new objects either, as the objects in persons1 do already have the desired properties and only need to be filtered.
I have updated the answer using a hybrid approach. Thanks a lot for the feedback.
Thanks you very much. But i have a question : why we need param: (a, b) -> a Because when i try code : Map<String, String> idToNameMap = persons.stream() .collect(Collectors.toMap(Person1::getId, Person1::getName)); persons .stream() .filter(item -> idToNameMap.containsKey(item.getId())) .forEach(item -> item.setName(idToNameMap.get(item.getId()))); person.stream().forEach(System.out::println); It same result with you. Can you explain me a thing about it
|
1

It's not the most beautiful answer etc but i guess it's gonna help u get idea how its work.

List<Person> collect = persons.stream()
        .filter(person -> persons1.stream().anyMatch(person1 -> person1.getId() == person.getId()))
        .map(person -> {
            Person1 getted = persons1.stream()
                .filter(person1 -> person1.getId() == person.getId())
                .findAny()
                .orElseGet(null);
            if (getted == null) throw new IllegalStateException("Should be Impossible");
            person.setName(getted.getName());
            return person;
        })
        .collect(Collectors.toList());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.