了解Stram
java8中最重要的改变一个是lambda表达式,另一个则是Stram API(java.util.stram.*)
Stream是java8中处理集合的关键抽象类概念,它可以指定你希望对集合进行的操作,可以知晓非常复杂的查找,过过滤和映射数据等操作.使用streamAPI对集合数据进行操作,就类似使用sql执行的数据库查询,简而言之Stream提供了一种高效且易于使用的处理数据的方式
创建Stream的基本操作
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Main{
    public static void main(String[] args) {
        //可以通过collection提供的stream()或paralllelStream()获取stream
        List<String>list=new ArrayList<>();
        Stream<String> stream1=list.stream();
        //通过Array中的静态方法stream()获取数组流
        Integer [] integers=new Integer[4];
        Stream<Integer> stream2 = Arrays.stream(integers);
        //通过stream中的静态方法of()
        Stream<String>stream3=Stream.of("1","1","2");
        //创建无限流
        //迭代
        Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);
//        stream4.forEach(System.out::println);
        //生成5个
        Stream<Double> limit = Stream.generate(() -> Math.random())
                .limit(5);//创建五个
    }
}筛选与切片
中间操作
多个中间操作可以连接起来成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理,二在终止操作时一次性全部处理,成为惰性请求
| 方法 | 描述 | 
|---|---|
| filter(Predicate p) | 接收lambda,从流水线中排除某些元素 | 
| distinct() | 筛选,通过流所生成的元素的HAshCode()和equals()去除重复元素 | 
| limit(long maxSize) | 截断流,使元素不超过给定数量 | 
| skip(long n) | 跳过元素,返回一个人掉了前n个元素的流.若流中元素不足n个元素.若流中元素不足n个,则返回一个空流.与limit(n)互补 | 
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
class User {
    private int score;
    private int age;
    public User(int score, int age){
        super();
        this.score = score;
        this.age = age;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return score == user.score &&
                age == user.age;
    }
    @Override
    public int hashCode() {
        return Objects.hash(score, age);
    }
    @Override
    public String toString() {
        return "User{" +
                "score=" + score +
                ", age=" + age +
                '}';
    }
}
//内部迭代,迭代操作都由Stream来完成了
class Main{
    static List<User>list= Arrays.asList(
        new User(1,2),
        new User(2,4),
        new User(3,6),
        new User(3,90),
        new User(3,90)
    );
    public static void main(String[] args) {
        //中间操作,不会执行任何操作
        //这条语句的意思是去俩条年龄小鱼35的user数据
        Stream<User> stream = list.stream().filter((e) -> e.getAge() < 35).limit(2);
        //终止操作:一次性执行全部内容
        stream.forEach(System.out::println);
        //覆盖equals和Hashcode去重
        list.stream().distinct().forEach(System.out::println);
    }
}映射
map-接受Lambda,讲元素转换成其他形式或提取信息.接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成为元素
flatMap-接受一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
class User {
    private int score;
    private int age;
    public User(int score, int age){
        super();
        this.score = score;
        this.age = age;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return score == user.score &&
                age == user.age;
    }
    @Override
    public int hashCode() {
        return Objects.hash(score, age);
    }
    @Override
    public String toString() {
        return "User{" +
                "score=" + score +
                ", age=" + age +
                '}';
    }
}
//内部迭代,迭代操作都由Stream来完成了
class Main{
    public static void main(String[] args) {
        List<String> list = Arrays.asList("aaa", "bbb", "#ccc", "ddd");
        list.stream()
                .map((str)->str.toUpperCase()).forEach(System.out::println);
        //AAA
        //BBB
        //#CCC
        //DDD
        System.out.println("----------------");
        //获取String的Hashcode值
        list.stream().map(String::hashCode).forEach(System.out::println);
        System.out.println("--------------------------");
        //因为Main::filterCharcter返回的是Stream<Character>,
        //所以整个返回的是Stream<Stream<Character>> 类型
        Stream<Stream<Character>> stream = list.stream().map(Main::filterCharcter);
        stream.forEach((sm)->{
            sm.forEach(System.out::println);//这样就能够逐一输出其中的字符
        });
        System.out.println("----------------以下可以用floatMap做简化操作");
        //这里得到的是一个流,把多个流中的元素抽取出来整合成一个流
        // map是把一个个流加入当前的流中,flatmap是把流中一个个元素加到流中
        Stream<Character> sm = list.stream().flatMap(Main::filterCharcter);
        sm.forEach(System.out::println);//和上面的输出结果是一样的
    }
    //函数的作用是传入一个string类型,将string类型转成一个个的字符
    // 添加到list中并返回list对应的stream
    public static Stream<Character>filterCharcter(String str){
        List<Character>list=new ArrayList<>();
        for (Character ch:str.toCharArray()){
            list.add(ch);
        }
        return list.stream();
    }
}
排序
sorted()自然排序 Comparable
sorted(Comparator com)指定排序 Comparator
class Main{
    public static void main(String[] args) {
        List<Integer>list=Arrays.asList(1,3,5,8,2);
        //自然排序 默认是升序
        list.stream().sorted().forEach(System.out::println);//1 2 3 5 8
        System.out.println("-------");
        //指定排序,降序排列
        list.stream().sorted((s1,s2)->s2-s1).forEach(System.out::println);//8 5 3 1 2
    }
}
终止操作
查找与匹配
boolean allMatch(Predicate<? super T> predicate);-检查是否匹配所有元素,传入一个对应的泛型,返回boolean值
boolean anyMatch(Predicate<? super T> predicate);检查是否匹配一个元素,传入一个对应的泛型,返回boolean
boolean noneMatch(Predicate<? super T> predicate);检查是否没有匹配一个元素,返回boolean
Optional<T> findFirst();返回一个Optional类中,泛型是自己的方法
long count();获取流中的总数
Optional<T> max(Comparator<? super T> comparator);传入比较方法(覆盖Comparator接口),返回最大值
Optional<T> min(Comparator<? super T> comparator);传入比较方法,返回最小值
归约与收集
归约
reduce(T iden,BinaryOperator b)可以将流中元素结合起来得到一个新值
reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值返回Option<T>
map和reduce的连接通常称为map-reduce模式,因google用它来进行网络搜索而出名
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
class User {
    private Status status;
    private int score;
    private int age;
    public User(int score, int age,Status status){
        super();
        this.score = score;
        this.age = age;
        this.status=status;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public enum Status{
        FREE,
        BUSY,
        VOCATION;
    }
    public Status getStatus() {
        return status;
    }
    public void setStatus(Status status) {
        this.status = status;
    }
    @Override
    public String toString() {
        return "User{" +
                "status=" + status +
                ", score=" + score +
                ", age=" + age +
                '}';
    }
    static List<User> list= Arrays.asList(
            new User(1,2,Status.VOCATION),
            new User(2,4,Status.FREE),
            new User(3,6,Status.FREE),
            new User(3,90,Status.VOCATION),
            new User(3,90,Status.BUSY)
    );
    public static void main(String[] args) {
       List<Integer>list2=Arrays.asList(1,2,3,4,5,6,7,8,9);
       //reduce()第一个参数是初始值,,第二个是二元运算
        Integer reduce = list2.stream().reduce(0, (x, y) -> x + y);
        System.out.println(reduce);//45
        //求出用户年龄的总和
        Optional<Integer> reduce1 = list.stream().map(User::getAge).reduce(Integer::sum);
        System.out.println("用户年龄总和为:"+reduce1.get());
    }
}收集
collect (Collector c)将流转换为其他形式.接受一个Collector接口的实现,用于给Stream中元素做汇总方法
import java.util.*;
import java.util.stream.Collectors;
class User {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    private Status status;
    private int score;
    private int age;
    public User(int score, int age,Status status,String name){
        super();
        this.score = score;
        this.age = age;
        this.status=status;
        this.name=name;
    }
    public int getScore() {
        return score;
    }
    public void setScore(int score) {
        this.score = score;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public enum Status{
        FREE,
        BUSY,
        VOCATION;
    }
    public Status getStatus() {
        return status;
    }
    public void setStatus(Status status) {
        this.status = status;
    }
    @Override
    public String toString() {
        return "User{" +
                "status=" + status +
                ", score=" + score +
                ", age=" + age +
                '}';
    }
    static List<User> list= Arrays.asList(
            new User(1,2,Status.VOCATION,"张三"),
            new User(2,4,Status.FREE,"李四"),
            new User(3,6,Status.FREE,"王五"),
            new User(3,90,Status.VOCATION,"赵六"),
            new User(3,90,Status.BUSY,"小黑")
    );
    public static void main(String[] args) {
        //取出全部的成绩封装到list集合中
        List<Integer> collect = list.stream().map(User::getScore)
                .collect(Collectors.toList());
        collect.forEach(System.out::println);
        //封装到指定的集合当中
        HashSet<Integer> collect1 = list.stream().map(User::getScore)
                .collect(Collectors.toCollection(HashSet::new));
        System.out.println(collect1);//[1, 2, 3]
        //计算总用户数量
        Long collect2 = list.stream().collect(Collectors.counting());
        System.out.println(collect2);//5
        //计算年龄总和
        Double collect3 = list.stream().collect(Collectors.summingDouble(User::getAge));
        System.out.println(collect3);
        //用逗号分隔每一个name字段,前后用【】
        String collect4 = list.stream().map(User::getName)
                .collect(Collectors.joining(",", "[", "]"));
        System.out.println(collect4);//[张三,李四,王五,赵六,小黑]
        String[]nums=new String[]{"1123","!23123","!@3123","12312"};
        String collect9 = Arrays.stream(nums).collect(Collectors.joining());
        System.out.println(collect9);
    }
}