Различный вложенный список, сравнение элементов списка по свойствам значений, Java8 Lambda - PullRequest
0 голосов
/ 01 октября 2019

У меня есть вложенный список с пользовательским объектом, то есть: класс Person

Теперь я хочу сравнить элементы по значению, например, предложить код.

Теперь у меня есть вложенный список, но янужно создать уникальный список в моем списке контейнеров.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.IntStream;


public class DistinctNestedListComparingByValueProperties {

    public static void main(String[] args) {

        List<Person> listA = Arrays.asList(new Person("a", 0), new Person("b", 1));
        List<Person> listB = Arrays.asList(new Person("a", 0), new Person("b", 1));
        boolean areEqual = equalListsByItemValues(listA, listB);
        if (areEqual) {
            System.out.println("Compared Lists Are Equal");
        } else {
            System.out.println("Compared Lists Are Different");
        }

        List<List<Person>> nestedPersonList = Arrays.asList(
                Arrays.asList(new Person("a", 0), new Person("b", 1)), //0
                Arrays.asList(new Person("a", 0), new Person("b", 1)), //1
                Arrays.asList(new Person("a", 0), new Person("b", 1)), //2
                Arrays.asList(new Person("a", 0), new Person("b", 1), new Person("c", 2)), //3
                Arrays.asList(new Person("a", 0), new Person("b", 1), new Person("c", 2)), //4
                Arrays.asList(new Person("a", 0)) // 5
        );


        nestedPersonList.forEach(System.out::println);
        System.out.println("\n");

        Set<List<Person>> distinctPersonLists = new HashSet<>(nestedPersonList);

        List<List<Person>> distinctNestedList = getDistinctItemsList(nestedPersonList);
        distinctNestedList.forEach(System.out::println);
    }

    public static List<List<Person>> getDistinctItemsList(List<List<Person>> nestedList) {
        List<List<Person>> distinctNestedList = new ArrayList<>();
        nestedList.forEach(personList -> {
            boolean isNotFound = distinctNestedList
                    .stream()
                    .filter(addedPersonList -> equalListsByItemValues(addedPersonList, personList))
                .count() == 0L;
            if (isNotFound) {
                distinctNestedList.add(personList);
            }
        });
        return distinctNestedList;
    }


    public static boolean equalListsByItemValues(List<?> listA, List<?> listB) {
        if (listA == null || listB == null) {
            return false;
        }
        if (listA.size() != listB.size()) {
            return false;
        }
         return IntStream.range(0, listA.size())
                 //Comparing By Value Properties (toString() based on)
                .filter(idx -> !String.valueOf(listA.get(idx)).equals(String.valueOf(listB.get(idx))))
                .count() == 0L;
    }

    public static class Person {

        private String name;
        private int age;

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

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

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Person other = (Person) obj;
            if (this.age != other.age) {
                return false;
            }
            if (!Objects.equals(this.name, other.name)) {
                return false;
            }
            return true;
        }

        @Override
        public String toString() {
            return "Person{" + "name=" + name + ", age=" + age + '}';
        }

    }
}

Хотя мой код работает, я хочу знать.

Как правильно это сделать, оптимизируямой код с Lambda Java 8? 1. Сравнение каждого элемента по его свойствам 2. Реализация различий во вложенном списке

Можно реализовать обобщенный (вложенный список) метода getDistinctItemsList

1 Ответ

0 голосов
/ 02 октября 2019

Спасибо, собираю ваши комментарии и исправляю методы equals и hashcode.

У меня работает код.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

public class DistinctNestedListComparingByValueProperties {

    public static void main(String[] args) {

        List<Person> listA = Arrays.asList(new Person("a", 0), new Person("b", 1));
        List<Person> listB = Arrays.asList(new Person("a", 0), new Person("b", 1));
        boolean areEqual = listA.equals(listB);
        if (areEqual) {
            System.out.println("Compared Lists Are Equal");
        } else {
            System.out.println("Compared Lists Are Different");
        }

        List<List<Person>> nestedPersonList = Arrays.asList(
                Arrays.asList(new Person("a", 0), new Person("b", 1)), //0
                Arrays.asList(new Person("a", 0), new Person("b", 1)), //1
                Arrays.asList(new Person("a", 0), new Person("b", 1)), //2
                Arrays.asList(new Person("a", 0), new Person("b", 1), new Person("c", 2)), //3
                Arrays.asList(new Person("a", 0), new Person("b", 1), new Person("c", 2)), //4
                Arrays.asList(new Person("a", 0)) // 5
        );


        nestedPersonList.forEach(System.out::println);
        System.out.println("\n");

        List<List<Person>> list = new ArrayList<>(new HashSet<>(nestedPersonList));
        list.stream().forEach(System.out::println);

    }

    public static class Person {

        private String name;
        private int age;

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

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

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 73 * hash + Objects.hashCode(this.name);
            hash = 73 * hash + this.age;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Person other = (Person) obj;
            if (this.age != other.age) {
                return false;
            }
            if (!Objects.equals(this.name, other.name)) {
                return false;
            }
            return true;
        }

        @Override
        public String toString() {
            return "Person{" + "name=" + name + ", age=" + age + '}';
        }

    }

}
...