java8 无限流_GitHub - huangbuhuan/java8: Java8学习

高效Java 8编程

用来记录Java 8学习,以及常用API的使用。

68747470733a2f2f696d672e736869656c64732e696f2f776572636b65722f63692f776572636b65722f646f63732e737667

68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6a617661253230737570706f72742d382d677265656e2e737667

68747470733a2f2f696d672e736869656c64732e696f2f64617669642f7374726f6e676c6f6f702f657870726573732e737667

目录:

函数式编程

函数式编程是一种编程范式,它的主要思想是把函数过程尽量写成一系列嵌套的函数调用。具有以下几个特点

函数是一等公民:函数和其他数据类型一样,可以赋值给其他变量,也可以作为参数,传递给另外一个函数,或者作为返回值返回。

没有副作用,不修改状态。

强调将计算过程分解成可复用的函数。

Lambda表达式

Lambda表达式没有名字,当它有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。

使用案例

Lambda示例

布尔表达式

(List list) -> list.isEmpty()

创建对象

() -> new User()

消费一个对象

(User user) -> {System.out.println(user.getName;)}

从一个对象中选择/抽取

(String s) -> s.length()

组合两个值

(int a, int b) -> a * b

比较两个对象

(User a1, User a2)

函数式接口

函数式接口就是仅仅声明了一个抽象方法的接口,不过函数式接口可以包含默认方法和静态方法。如下:

@FunctionalInterface

public interface FunctionInterfaceDemo {

void test();

static void say() {

System.out.println("hello");

}

default void play() {

}

}

Java8中重要的函数式接口

下面是Java 8中一些常用的函数式接口。

接口名

参数

返回类型

示例

Predicate

boolean

判断是否

Consumer

void

输出一个值

Function

R

获得Artist对象的名字

Supplier

None

T

工厂方法

UnaryOperator

T

T

逻辑非(!)

BinaryOperator

(T, T)

T

求两个数的乘积(*)

简单的使用例子:

Predicate predicate = x -> x == 1;

Consumer consumer = x -> System.out.println(x);

Function function = x -> x = x + 1;

Supplier supplier = () -> 1;

UnaryOperator unaryOperator = x -> x + 1;

BinaryOperator binaryOperator = (x, y) -> x * y;

Stream流

9351734f64b3d4e4aa1e32f6777eeead.png

Stream是一个借口继承了BaseStream接口,BaseStream接口继承了AutoCloseable接口。它只能被消费一次,如果想要继续使用,需要重新创建一个流。如下会抛出异常。

List strs = Arrays.asList("A", "B", "C");

Stream s = strs.stream();

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

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

内部迭代实现机制

外部迭代:首先调用Iterator方法,产生一个新的Iterator对象,进行控制迭代过程。

内部迭代:首先调用stream方法,它的作用和iterator()方法一样,不过它返回的是内部迭代中相应的接口Stream。这样做的好处就是在迭代时要进行多次操作时可以不用多次循环,只需要迭代一次就好了。

像filter这种不产生新集合的方法叫做惰性求值方法,像count这样最终会从Stream产生值的方法叫作及早求值方法。

例子:

User jack = User.of("Jack", 21, "杭州");

User rose = User.of("Rose", 18, "杭州");

List users = Arrays.asList(jack, rose);

users.stream()

.filter(user -> {

System.out.println(user.getName());

return user.getAge() > 20;

});

System.out.println("------------");

users.stream()

.filter(user -> {

System.out.println(user.getName());

return user.getAge() > 20;

}).count();

输出:

08d23b60aefbb5007fda26cf72794941.png

结论:只有在需要的时候进行计算可以更好的提示效率

常用的方法

collect方法

将Stream流转换为一个集合

#输入

Stream stream = Stream.of("a", "b", "c");

List strs = stream.collect(Collectors.toList());

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

#输出

a

b

c

filter方法

过滤掉流中不符合条件的元素

#输入

Stream nums = Stream.of(18, 19 ,20);

nums.filter(num -> num > 18).forEach(System.out::println);

#输出

c

map方法

将流中的元素转换为另外一个元素。

#输入

Stream nums = Stream.of(18, 19 ,20);

map(num -> num + 100).forEach(System.out::println);

#输出

118

119

120

flatMap方法

将底层的元素全部抽出来放到一起,如下将List中的元素全部抽取出来,流中只包含Integer元素。

List nums1 = Arrays.asList(1, 2, 3);

List nums2 = Arrays.asList(4, 6);

Stream.of(nums1, nums2).flatMap(num -> num.stream()).forEach(System.out::println);

reduce方法

将Stream流中的数据聚合成一个数据

50a5e54e600094baa508088a210ded23.png

#输入

int ages = Stream.of(1, 2, 34).reduce(0, (a, b) -> a + b);

System.out.println(ages);

#输出

37

创建无限流

Stream的API提供了两个静态方法创建无限流:iterate和generate。由两个静态方法创建的流会根据给定的函数按需创建流一般会使用limit限制流的大小。iterate方法会对每个新生成的值都调用函数,generate方法不会对每个新生成的值应用函数.

// 从0开始,生成10个偶数。

Stream.iterate(0, n -> n + 2).limit(10).forEach(System.out::println);

// 生成10个随机数。

Stream.generate(Math::random). limit(10).forEach(System.out::println);

其他方法

skip:跳过指定个数的流。

limit:返回不超过给定长度的流。

max:找到最大的元素

min:找到最小的元素

findFirst:找到第一个匹配元素

findAny:获取任意一个元素

anyMatch:是否存在一个匹配元素

noneMatch:是否全部不匹配

allMatch:是否全部匹配

sorted:排序

distinct:去重

高效Java8编程

其他

Optional

Optional是为了减少NullPointException,增加代码的可读性。Optional是一个final类型的类

Optional optUser = Optional.of(user);

empty:返回一个空的Optional实例。

filter:如果满足提交返回Optional对象,否则返回一个空的Optional对象。

flatMap:如果值存在,就使用mapping函数调用,返回一个Optional对象,否则返回一个空对象。

get:如果值存在返回用Optional封装返回,否则抛出NoSuchElementException异常

ifPresent:如果值存在,就返回该方法的调用,否则什么也不做。

isPresent:如果值存在,就返回true,否则返回false。

map:如果值存在,就执行提供的mapping函数调用。

of:如果值不存在就抛出异常,否则返回一个Optional封装的对象。

ofNullable:如果值为空就返回一个空的Optional对象,否则调用of方法。

orElse:如果值存在就返回该值,否则返回默认值。

orElseGet:如果值存在就返回该值,否则返回一个函数接口生成的值。

orElseThrow:如果值存在就返回该值,否则抛出一个接口生成的异常。

DateTime

在Java 8 以前需要使用Date和SimpdateFormatter操作时间,而且都不是线程安全的,Date不仅包含日期还包含时间和毫秒数,使用起来非常的困难,而Java 8把日期分成了LocalDate和LocalTime,还有LocalDateTime。

使用LocalDate操作日期

// 获取当前日期

LocalDate now = LocalDate.now();

// 用静态方法创建日期

LocalDate date = LocalDate.of(2017, 5, 1);

// 将String类型转换为日期类型.注:02不能写成2,否则会抛出DateTimeParseException

LocalDate endOfFeb = LocalDate.parse("2017-02-28");

// 获取这个月的第一天的日期

now.with(TemporalAdjusters.firstDayOfMonth())

// 获取这个月的最后一天

now.with(TemporalAdjusters.lastDayOfMonth())

使用LocalTime操作时间

// 获取当前时间

LocalTime now = LocalTime.now();

// 舍弃纳秒

now.withNano(0);

/*

* 获取特定的时间

* Localtime.MIN 00:00

* Localtime.MIDNIGHT 00:00

* Localtime.NOON 12:00

* LocalTime.MAX 23:59:59.999999999

*/

now.with(LocalTime.MIN);

now.with(LocalTime.MIDNIGHT);

now.with(LocalTime.NOON);

now.with(LocalTime.MAX);

// of可以传入四个参数

LocalTime zero = LocalTime.of(23, 59, 59, 999_999_999);

// parse方法可以转换的格式有 HH:mm:ss.nnnnnnnnn HH:mm:ss HH:mm

LocalTime last = LocalTime.parse("23:59:59.999999999");

// 也可以自定义转换格式

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");

LocalTime start = LocalTime.parse("00:00:00", formatter);

JDBC映射和新类型关联

date -> LocalDate

time -> LocalTime

timestamp -> LocalDateTime

代码地址

参考链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值