использовать отдельный()
Вы можете использовать Stream.distinct() для фильтрации одних и тех же элементов, например:
Collection<String> list = Arrays.asList("A", "B", "C", "D", "A", "B", "C");
// Get collection without duplicate i.e. distinct only
List<String> distinctElements = list.stream().distinct().collect(Collectors.toList());
//Let's verify distinct elements
System.out.println(distinctElements);
Фильтрация через функцию different() очень проста и удобна, но в большинстве случаев обрабатываемые объекты более сложные, например содержащие различные атрибуты и т.д., и редко обрабатываются только примитивные типы и строки. Мы можем обрабатывать сложные объекты, настроив интерфейс Predicate, например:
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor)
{
Map<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
Этот метод очень прост и использует ConcurrentHashMap, чтобы определить, содержится ли элемент, который принимает ссылку на функциональный объект. Давайте воспользуемся этим методом
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class JavaStreamDistinctExamples
{
public static void main(String[] args)
{
Person lokesh = new Person(1, "Lokesh", "Gupta");
Person brian = new Person(2, "Brian", "Clooney");
Person alex = new Person(3, "Alex", "Kolen");
//Add some random persons
Collection<Person> list = Arrays.asList(lokesh,brian,alex,lokesh,brian,lokesh);
// Get distinct only
List<Person> distinctElements = list.stream().filter(distinctByKey(p -> p.getId())).collect(Collectors.toList());
// Let's verify distinct elements
System.out.println(distinctElements);
}
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor)
{
Map<Object, Boolean> map = new ConcurrentHashMap<>();
return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
class Person
{
public Person(Integer id, String fname, String lname) {
super();
this.id = id;
this.fname = fname;
this.lname = lname;
}
private Integer id;
private String fname;
private String lname;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
@Override
public String toString() {
return "Person [id=" + id + ", fname=" + fname + ", lname=" + lname + "]";
}
}
Для тех, кто плохо знаком с функциональным программированием на Java 8.
List<Person> distinctElements = list.stream().filter(distinctByKey(p -> p.getId())).collect(Collectors.toList());
Может быть сложно понять, на самом деле это аббревиатура следующего вида
List<Person> distinctElements = list.stream().filter(distinctByKey(new Function<Person, Object>() {
@Override
public Object apply(Person person) {
return person.getId();
}
})).collect(Collectors.toList());
Используйте max() и min()
Для max и min вам нужно только передать им компаратор, и вы можете сравнить их, чтобы получить максимальное и минимальное значения.
Получить максимальную и минимальную дату
LocalDate start = LocalDate.now();
LocalDate end = LocalDate.now().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
List<LocalDate> dates = Stream.iterate(start, date -> date.plusDays(1))
.limit(ChronoUnit.DAYS.between(start, end))
.collect(Collectors.toList());
// Get Min or Max Date
LocalDate maxDate = dates.stream().max( Comparator.comparing( LocalDate::toEpochDay ) ).get();
LocalDate minDate = dates.stream().min( Comparator.comparing( LocalDate::toEpochDay ) ).get();
System.out.println("maxDate = " + maxDate);
System.out.println("minDate = " + minDate);
Получить максимальное и минимальное число
Integer maxNumber = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.max(Comparator.comparing(Integer::valueOf)).get();
Integer minNumber = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
.min(Comparator.comparing(Integer::valueOf)).get();
System.out.println("maxNumber = " + maxNumber);
System.out.println("minNumber = " + minNumber);
Получить самый большой символ или строку
String maxChar = Stream.of("H", "T", "D", "I", "J").max(Comparator.comparing(String::valueOf)).get();
String minChar = Stream.of("H", "T", "D", "I", "J").min(Comparator.comparing(String::valueOf)).get();
System.out.println("maxChar = " + maxChar);
System.out.println("minChar = " + minChar);
Получить самый большой и самый маленький объект
List<Employee> emps = new ArrayList<Employee>();
emps.add(new Employee(1, "Lokesh", 36));
emps.add(new Employee(2, "Alex", 46));
emps.add(new Employee(3, "Brian", 52));
Comparator<Employee> comparator = Comparator.comparing(Employee::getAge);
// Get Min or Max Object
Employee minObject = emps.stream().min(comparator).get();
Employee maxObject = emps.stream().max(comparator).get();
System.out.println("minObject = " + minObject);
System.out.println("maxObject = " + maxObject);
class Employee {
private int id;
private String name;
private int age;
public Employee(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 String toString() {
StringBuilder str = null;
str = new StringBuilder();
str.append("Id:- " + getId() + " Name:- " + getName() + " Age:- " + getAge());
return str.toString();
}
}
Статьи по Теме