Java最新Java8新特性:Stream API,StringBoot编程式事务与声明式事务

我的面试宝典:一线互联网大厂Java核心面试题库

以下是我个人的一些做法,希望可以给各位提供一些帮助:

整理了很长一段时间,拿来复习面试刷题非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!

image

283页的Java进阶核心pdf文档

Java部分:Java基础,集合,并发,多线程,JVM,设计模式

数据结构算法:Java算法,数据结构

开源框架部分:Spring,MyBatis,MVC,netty,tomcat

分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等

微服务部分:SpringBoot,SpringCloud,Dubbo,Docker

image

还有源码相关的阅读学习

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

注意:

①Stream 自己不会存储元素。

②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。

③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

二 Stream 的三个操作步骤:

=================

  1. 创建 Stream(4种方式)

由一个数据源(如:集合、数组)获取一个流

  1. 中间操作(筛选与切片、映射、排序)

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

3.终止操作(也称为终端操作)

一个终止操作,执行中间操作链,并产生结果

三 创建Stream

===========

3.1 创建Stream的四种方式


1) Collection 接口提供了 两个获取流的方法:stream()和parallelStream()方法

 default Stream stream() : 返回一个顺序流 

default Stream parallelStream() : 返回一个并行流

2) Arrays 的静态方法 stream() 可 以获取数组流:

 static Stream stream(T[] array): 返回一个流

重载形式,能够处理对应基本类型的数组:

 public static IntStream stream(int[] array)

 public static LongStream stream(long[] array)

 public static DoubleStream stream(double[] array)

3)可以使用Steram类的静态方法 Stream.of(), 通过显示值 创建一个流。它可以接收任意数量的参数。

 public static Stream of(T… values) : 返回一个流

4)创建无限流:可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。

 迭代

public static Stream iterate(final T seed, final UnaryOperator f)

 生成

public static Stream generate(Supplier s) :

3.2 创建Stream的案例


//1. 创建 Stream(四种方式)

@Test

public void test1(){

//1. Collection 提供了两个方法 stream() 与 parallelStream()

List list = new ArrayList<>();

Stream stream = list.stream(); //获取一个顺序流

Stream parallelStream = list.parallelStream(); //获取一个并行流

//2. 通过 Arrays 中的 stream() 获取一个数组流

Integer[] nums = new Integer[10];

Stream stream1 = Arrays.stream(nums);

//3. 通过 Stream 类中静态方法 of()

Stream stream2 = Stream.of(1,2,3,4,5,6);

//4. 创建无限流

//4.1 迭代

Stream stream3 = Stream.iterate(0, (x) -> x + 2).limit(10);

stream3.forEach(System.out::println);

//4.2 生成

Stream stream4 = Stream.generate(Math::random).limit(2);

stream4.forEach(System.out::println);

}

四 中间操作

======

多个中间操作可以连接起来形成一个流水线,除非流水 线上触发终止操作,否则中间操作不会执行任何的处理! 而在终止操作时一次性全部处理,称为**“惰性求值”**。

4.1 中间操作一:筛选与切片


4.1.1 筛选与切片方法

4.1.2 筛选与切片案例:

//2. 中间操作

List emps = Arrays.asList(

new Employee(102, “李四”, 59, 6666.66),

new Employee(101, “张三”, 18, 9999.99),

new Employee(103, “王五”, 28, 3333.33),

new Employee(104, “赵六”, 8, 7777.77),

new Employee(104, “赵六”, 8, 7777.77),

new Employee(104, “赵六”, 8, 7777.77),

new Employee(105, “田七”, 38, 5555.55)

);

/*

筛选与切片

filter(Lambda)——接收 Lambda , 从流中排除某些元素。

limit(n)——截断流,使其元素不超过给定数量n。

skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补

distinct()——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素

*/

//filter(Predicate p)

//内部迭代:迭代操作 Stream API 内部完成

@Test

public void test2(){

//所有的中间操作不会做任何的处理

Stream stream = emps.stream()

.filter((e) -> {

System.out.println(“测试中间操作”);

return e.getAge() <= 35;

});

//只有当做终止操作时,所有的中间操作会一次性的全部执行,称为“惰性求值”

stream.forEach(System.out::println);

}

//外部迭代

@Test

public void test3(){

Iterator it = emps.iterator();

while(it.hasNext()){

System.out.println(it.next());

}

}

//limit(long maxSize)

@Test

public void test4(){

emps.stream()

.filter((e) -> {

System.out.println(“短路!”); // && ||

return e.getSalary() >= 5000;

}).limit(3)

.forEach(System.out::println);

}

//skip(long n)

@Test

public void test5(){

emps.parallelStream()

.filter((e) -> e.getSalary() >= 5000)

.skip(2)

.forEach(System.out::println);

}

//distinct()

@Test

public void test6(){

emps.stream()

.distinct()

.forEach(System.out::println);

}

test2()和test3()是filter(Predicate p)内部迭代与Iterator外部迭代的对比。在test2()中,Stream API帮助我们完成了迭代,对集合emps内的元素逐一完成filter(Predicate p)内Lambda表达式中的内容(先输出“测试中间操作”后返回判断结果)。

4.2 中间操作二:映射


4.2.1 映射方法

4.2.2 映射案例:

public class TestStreamAPI1 {

List emps = Arrays.asList(

new Employee(102, “李四”, 59, 6666.66),

new Employee(101, “张三”, 18, 9999.99),

new Employee(103, “王五”, 28, 3333.33),

new Employee(104, “赵六”, 8, 7777.77),

new Employee(104, “赵六”, 8, 7777.77),

new Employee(104, “赵六”, 8, 7777.77),

new Employee(105, “田七”, 38, 5555.55)

);

//2. 中间操作

/*

映射

map——接收 Lambda , 将元素转换成其他形式或提取信息。接收一个函数作为参数,

该函数会被应用到每个元素上,并将其映射成一个新的元素。

flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

*/

@Test

public void test1(){

Stream str = emps.stream()

.map((e) -> e.getName());

System.out.println(“-------------------------------------------”);

List strList = Arrays.asList(“aaa”, “bbb”, “ccc”, “ddd”, “eee”);

Stream stream = strList.stream()

.map(String::toUpperCase);

stream.forEach(System.out::println);

//stream2:流中元素是流Stream,因为filterCharacter返回的是一个流

Stream<Stream> stream2 = strList.stream()

.map(TestStreamAPI1::filterCharacter);

//{{a,a,a},{b,b,b},{c,c,c},{d,d,d},{e,e,e}},filterCharacter返回的小流在大流中

stream2.forEach((sm) -> {

sm.forEach(System.out::println);

});

System.out.println(“---------------------------------------------”);

//flatMap将filterCharacter返回的所有流连接成了一个流,可以理解为

//将filterCharacter返回的流中元素取出来放到流stream3中

Stream stream3 = strList.stream()

.flatMap(TestStreamAPI1::filterCharacter);

//{a,a,a,b,b,b,c,c,c,d,d,d,e,e,e},将filterCharacter返回的小流连接成大流

stream3.forEach(System.out::println);

}

public static Stream filterCharacter(String str){

List list = new ArrayList<>();

for (Character ch : str.toCharArray()) {

list.add(ch);

}

return list.stream();

}

}

注意区别test1()中的stream2和stream3; 对于map(Function f) 是通过函数将流中每一个素映射成一个新的元素,而filterCharacter函数是将传进去的String中的每个字符添加到List中,并通过集合返回流,所以stream2中的元素是流Stream(得到的结果为{{a,a,a},{b,b,b},{c,c,c},{d,d,d},{e,e,e}});对于flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另 一个流,然后把所有流连接成一个流,其将filterCharacter返回的所有流连接成了一个流,可以理解为将filterCharacter返回的流中元素取出来放到流stream3中(得到的结果为{a,a,a,b,b,b,c,c,c,d,d,d,e,e,e})。

map(Function f)和flatMap(Function f)的区别可以类比于集合的add(Object obj)和addAll(Collection coll)两个方法的区别,假设add方法传进去的参数是一个集合,意味着形参集合被添加进调用方法的集合中(当前集合),而addAll方法会将传进去的集合中的每一个元素添加到当前集合中。

4.3 中间操作三:排序


4.3.1 排序方法

4.3.2 排序案例:

//2. 中间操作

/*

排序

sorted()——自然排序(Comparable中的comparaTo方法)

sorted(Comparator com)——定制排序

*/

@Test

public void test2(){

emps.stream()

.map(Employee::getName)

.sorted()//自然排序:String实现了Comparable接口并重写了comparaTo方法

.forEach(System.out::println);

System.out.println(“------------------------------------”);

emps.stream()

.sorted((x, y) -> {

if(x.getAge() == y.getAge()){

return x.getName().compareTo(y.getName());

}else{

return Integer.compare(x.getAge(), y.getAge());

}

}).forEach(System.out::println);

}

对于定制排序,需要使用Lambda表达式取代Comparator函数式接口的匿名内部实现类重写compare方法。

五 终止操作

======

5.1 终止操作一:查找与匹配


5.1.1 查找与匹配方法

5.1.2 查找与匹配案例

//3. 终止操作

/*

查找与匹配

allMatch——检查是否匹配所有元素

anyMatch——检查是否至少匹配一个元素

noneMatch——检查是否没有匹配的元素

findFirst——返回第一个元素

findAny——返回当前流中的任意元素

count——返回流中元素的总个数

max——返回流中最大值

min——返回流中最小值

*/

@Test

public void test1(){

//allMatch(Predicate p)

boolean bl = emps.stream()

.allMatch((e) -> e.getStatus().equals(Status.BUSY));

System.out.println(bl);

//anyMatch(Predicate p)

boolean bl1 = emps.stream()

.anyMatch((e) -> e.getStatus().equals(Status.BUSY));

System.out.println(bl1);

//noneMatch(Predicate p)

boolean bl2 = emps.stream()

.noneMatch((e) -> e.getStatus().equals(Status.BUSY));

System.out.println(bl2);

}

@Test

public void test2(){

//findFirst()

//Optional可以避免空指针异常,最终的结果有可能为空时,将这样的结果封装到Optional

Optional op = emps.stream()

.sorted((e1, e2) -> -Double.compare(e1.getSalary(), e2.getSalary()))//默认从小到大排序,加负号后从大到小排

.findFirst();

System.out.println(op.get());

System.out.println(“--------------------------------”);

//findAny()

//Optional可以避免空指针异常

Optional op2 = emps.parallelStream()//并行流:多个线程同事去找状态为FREE的;串行流:一个线程挨个找

.filter((e) -> e.getStatus().equals(Status.FREE))

.findAny();

System.out.println(op2.get());

}

@Test

public void test3(){

//count()

long count = emps.stream()

.filter((e) -> e.getStatus().equals(Status.FREE))

.count();

System.out.println(count);

//max(Comparator c):获取工资最大的员工的工资

Optional op = emps.stream()

.map(Employee::getSalary)

.max(Double::compare);

System.out.println(op.get());

//min(Comparator c) :获取工资最小的员工

Optional op2 = emps.stream()

.min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));

//.min(Double::compare());

System.out.println(op2.get());

}

//注意:流进行了终止操作后,不能再次使用

@Test

public void test4(){

Stream stream = emps.stream()

.filter((e) -> e.getStatus().equals(Status.FREE));

long count = stream.count();

stream.map(Employee::getSalary)

.max(Double::compare);

}

5.2 终止操作二:规约


5.2.1 规约方法

5.2.2 规约案例

这里会用到Employee类(之前的博客都用的该pojo类),与之前不同的是,Employee新增了一个属性staus,具体代码如下:

public class Employee {

private int id;

private String name;

private int age;

private double salary;

private Status status;

//空参,全参构造器

//getter,setter方法

//重写hashcode(),equals(),toString()方法

//…

public enum Status {

FREE, BUSY, VOCATION;

}

总结

如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了

《Java中高级核心知识全面解析》

小米商场项目实战,别再担心面试没有实战项目:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

)

5.2.2 规约案例

这里会用到Employee类(之前的博客都用的该pojo类),与之前不同的是,Employee新增了一个属性staus,具体代码如下:

public class Employee {

private int id;

private String name;

private int age;

private double salary;

private Status status;

//空参,全参构造器

//getter,setter方法

//重写hashcode(),equals(),toString()方法

//…

public enum Status {

FREE, BUSY, VOCATION;

}

总结

如果你选择了IT行业并坚定的走下去,这个方向肯定是没有一丝问题的,这是个高薪行业,但是高薪是凭自己的努力学习获取来的,这次我把P8大佬用过的一些学习笔记(pdf)都整理在本文中了

《Java中高级核心知识全面解析》

[外链图片转存中…(img-KtxA5weP-1715373268847)]

小米商场项目实战,别再担心面试没有实战项目:

[外链图片转存中…(img-9ETC8WkQ-1715373268847)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值