/* package whatever; // don't place package name! */

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import static java.util.stream.Collectors.toList;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{

    public static void main(String[] args) {
        List<Person> listPersons = Arrays.asList(
                new Person(1, "person1"),
                new Person(1, "person5"),
                new Person(2, "person2"),
                new Person(1, "person1"),
                new Person(1, "person2"),
                new Person(1, "person1"),
                new Person(3, "person3")
        );
        List<Person> persons = listPersons.stream()
                .filter(distinctByKey(pr -> pr.getId() + " " + pr.getName()))
                .collect(toList());

        persons.forEach(System.out::println);
    }

    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

}

class Person {

    private int id;
    private String name;

    public Person() {
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

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

}