了解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);
    }
}
Last modification:November 20, 2023
如果觉得我的文章对你有用,请随意赞赏