Java8基础教程-Stream示例,distin

使用distinct()

可以使用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);复制代码

通过distinct()函数过滤非常的简单容易,但是大多数情况下,处理的对象多会比较复杂,例如包含各种属性等,很少会只处理原生类型和字符串。 我们可以通过定制一个 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,只需要给他们传递一个Comparator,就可以进行比较,从而获取最大和最小值。

获取最大,最小得日期
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);复制代码
获取最大的char或者String
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();
    }
} 复制代码

相关文章