java基础学习-Stream API

mybatis 中 #{}和 ${}的区别是什么?
1、#{}带引号,${}不带引号;
2、#{}可以防止SQL注入;
3、${}常用于数据库表名、order by子句;
4、一般能用#{}就不要使用${};

1、Stream的操作步骤

Stream有如下三个操作步骤:

一、创建Stream

从一个数据源,如集合、数组中获取流。

二、中间操作

一个操作的中间链,对数据源的数据进行操作。

三、终止操作

一个终止操作,执行中间操作链,并产生结果。
要注意的是,对流的操作完成后需要进行关闭操作(或者用JAVA7的try-with-resources)。

@Data
class Student{
    private String name;
    private Integer age;
    private String status;
    private char sex;

    public Person(String name, Integer age, String status, char sex) {
        this.name = name;
        this.age = age;
        this.status= status;
        this.sex = sex;
    }
}
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("学生1",18,"优秀",'F'));
studentList.add(new Student("学生2",24,"良好",'M'));
studentList.add(new Student("学生3",22,"良好",'F'));
studentList.add(new Student("学生4",20,"优秀",'M'));
studentList.add(new Student("学生5",22,"优秀",'M'));
studentList.add(new Student("学生6",20,"良好",'F'));
studentList.add(new Student("学生7",21,"合格",'F'));
studentList.add(new Student("学生8",22,"合格",'M'));

2、Stream中间操作--筛选与切片

  • filter:接收Lambda,从流中排除某些操作;
long goodNum = studentList.stream().filter((p) -> p.getStatus().equals("良好")||p.getStatus().equals("优秀")).count();//筛选优秀和良好的学生数量  结果:6
  • limit:截断流,使其元素不超过给定对象
//筛选女生前两条
studentList.stream().filter((p) -> p.getSex() == 'F').limit(2).forEach(System.out::println);

结果:
Student(name=学生1, age=18, status=优秀, sex=F)
Student(name=学生3, age=22, status=良好, sex=F)

  • skip(n):跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
//筛选女生第三四条
studentList.stream().filter((p) -> p.getSex() == 'F').skip(2).forEach(System.out::println);

结果:
Student(name=学生6, age=20, status=良好, sex=F)
Student(name=学生7, age=21, status=合格, sex=F)

  • distinct:筛选,通过流所生成元素的hashCode()和equals()去除重复元素。
studentList.stream().filter((p) -> p.getSex() == 'M').distinct().forEach(System.out::println);

3、Stream中间操作--映射

Stream map(Function<? super T, ? extends R> mapper);//参数是一个方法,可用lamdba表达式
map--接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatMap--接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

//提取某一列(以name为例)
List<String> studentDTOS = studentList.stream().map(s->s.getName()).collect(Collectors.toList());
//和上面返回一致
//List<String> studentDTOS = studentList.stream().map(Student::getName).collect(Collectors.toList());
System.out.println(studentDTOS.toString());

结果:
[学生1, 学生2, 学生3, 学生4, 学生5, 学生6, 学生7, 学生8]

@Data
public class StudentDTO {
    private String name;
    private String status;

    public StudentDTO(String name, String status) {
        this.name = name;
        this.status= status;
    }
}

//提取某几列(以name为例)
List<StudentDTO> studentDTOS1 = studentList.stream().map(s->{
            StudentDTO studentDTO = new StudentDTO(s.getName(),s.getStatus());
            return studentDTO;
        }).collect(Collectors.toList());
System.out.println(studentDTOS1.toString());

结果:
[StudentDTO(name=学生1, status=优秀), StudentDTO(name=学生2, status=良好), StudentDTO(name=学生3, status=良好), StudentDTO(name=学生4, status=优秀), StudentDTO(name=学生5, status=优秀), StudentDTO(name=学生6, status=良好), StudentDTO(name=学生7, status=合格), StudentDTO(name=学生8, status=合格)]

4、Stream中间操作--排序

sorted()--自然排序(Comparable)

List<Integer> ints = Arrays.asList(1,2,5,3,4);
//自然排序正序
ints.stream().sorted().forEach(System.out::println);
//自然排序倒序
ints.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println);

sorted(Comparator com)--定制排序(Comparator)
使用Comparator按照一个字段排序

//按照名字正序
studentList.stream().sorted(Comparator.comparing(Student::getName)).forEach(System.out::println);
//按照名字倒序
studentList.stream().sorted(Comparator.comparing(Student::getName,Comparator.reverseOrder())).forEach(System.out::println);

使用Comparator按照多个字段排序
通过Comparator.thenComparing(Comparator<? super T> other) 实现多字段排序,并且使用Comparator.reverseOrder() 实现降序和升序

//按照年龄升序,等级降序,名字降序
studentList.stream().sorted(Comparator.comparing(Student::getAge)
     .thenComparing(Student::getStatus,Comparator.reverseOrder())
     .thenComparing(Student::getName,Comparator.reverseOrder())).forEach(System.out::println);

5、终止操作--查找与匹配

allMatch--检查是否匹配所有元素 返回true。false
anyMatch--检查是否至少匹配一个元素 返回true。false

//年龄是否全部大于10
System.out.println(studentList.stream().anyMatch(s->s.getAge()>10));
//是否至少有一条数据 年龄大于24并且等级是良好
System.out.println(studentList.stream().anyMatch(s->s.getAge()>23&&"良好".equals(s.getStatus())));

noneMatch--检查是否没有匹配所有元素
findFirst--返回第一个元素
findAny--返回当前流中的任意元素
count--返回流中元素的总个数
max--返回流中最大值
min--返回流中最小值

//年龄是否全部不大于10
System.out.println("年龄是否全部不大于10:"+studentList.stream().noneMatch(s->s.getAge()>10));
System.out.println("list中第一条数据:"+studentList.stream().findFirst());
System.out.println("list中任意一条数据:"+studentList.stream().findAny());
System.out.println("list中数据件数:"+studentList.stream().count());
System.out.println("list中年龄最大值:"+studentList.stream().max(Comparator.comparing(Student::getAge)));
System.out.println("list中年龄最小值:"+studentList.stream().min(Comparator.comparing(Student::getAge)));

6.归约reduce

Stream API的归约操作可以将流中元素反复结合起来,得到一个值

//求1-100的和
List<Integer> integerList = new ArrayList<>(100);
for(int i = 1;i <= 100;i++) {
    integerList.add(i);
}
final Integer reduce = integerList.stream().reduce(0, (x, y) -> x + y);
System.out.println("结果为:" + reduce);
//求年龄和
Optional<Integer> ageReduce =  studentList.stream().map(Student::getAge).reduce(Integer::sum);
System.out.println(ageReduce);

7.集合

collect:将流转换为其他形式,接收一个Collector接口实现 ,用于给Stream中汇总的方法

7.1 将List转为另一个List

//将Student类型List转换为StudentDTO类型的List
        List<StudentDTO> studentDTOS1 = studentList.stream().map(s->{
            StudentDTO studentDTO = new StudentDTO(s.getName(),s.getStatus());
            return studentDTO;
        }).collect(Collectors.toList());
        System.out.println(studentDTOS1.toString());
        //将Student类型List转换为只有名字的List
        List<String> nameList = studentList.stream().map(Student::getName).distinct().collect(Collectors.toList());

7.2计算平均年龄,最大年龄

Double collect1 = studentList.stream().collect(Collectors.averagingInt(p -> p.getAge()));
System.out.println("平均年龄为:" + collect1);
Optional<Integer> collect2 = studentList.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compareTo));
System.out.println("最大年龄为:" + collect2);

8流的关闭

try(final Stream<Integer> integerStream = studentList.stream().map(Student::getAge)) {
            final Optional<Integer> minAge = integerStream.collect(Collectors.minBy(Integer::compareTo));
            System.out.println(minAge.get());
        }
所有博客均为自己学习的笔记。如有错误敬请理解。
原文地址:https://www.cnblogs.com/tangtang-benben/p/15238423.html