Java8 常用 API

Java8主要是在原来面向对象的基础上增加了函数式编程的能力。这样就出现了在Java中使用Lambda表达式,将一个函数作为方法的参数来进行传递。Java8的Stream就是典型的例子,Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。


一、Stream API

filter

1、统计

long count = data.stream().filter(i -> i > 20).count();
结果:5

2、过滤转换

List<Integer> list = data.stream().filter(i -> i > 20).collect(Collectors.toList());
结果:[27, 23, 99, 232, 56]

3、findFirst()

Optional<Integer> optional = data.stream().filter(i -> Objects.equals(27, i)).findFirst();
if (optional.isPresent()) {
System.out.println("存在,值为:" + optional.get());
} else {
System.out.println("不存在");
}
结果:存在,值为:27

4、findAny()

可以在集合中只要找到任何一个所匹配的元素,就返回

Integer any = data.stream().filter(i -> i > 50).findAny().get();
结果:99

Arrays.stream()

long count1 = Arrays.stream(arr).filter(i -> i > 20).count();
结果:7

Stream.of()

long count2 = Stream.of(arr).filter(i -> i > 20).count();
long sum = Stream.of(12, 77, 59, 3, 654).filter(i -> i > 20).mapToInt(Integer::intValue).sum();
System.out.println("count:" + count2 + ",sum:" + sum);
结果:count:7,sum:790

Stream.generate()

用来创建无限Stream的静态方法

Stream<String> stream = Stream.generate(() -> "test").limit(10);
String[] strArr = stream.toArray(String[]::new);
System.out.println(Arrays.toString(strArr));
结果:[test, test, test, test, test, test, test, test, test, test]

Stream.iterate()

用来创建无限Stream的静态方法

Stream<BigInteger> bigIntStream = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.TEN)).limit(10);
BigInteger[] bigIntArr = bigIntStream.toArray(BigInteger[]::new);
System.out.println(Arrays.toString(bigIntArr));
结果:[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]

map方法

将Integer类型转换成String类型

List<String> afterString = data.stream().map(i -> String.valueOf(i)).collect(Collectors.toList());

limit方法和skip方法

limit(n)方法会返回一个包含n个元素的新的流(若总长小于n则返回原始流) skip(n)方法正好相反,它会丢弃掉前面的n个元素。

List<Integer> list1 = data.stream().skip(4).limit(4).collect(Collectors.toList());
结果:[19, 27, 23, 99]

distinct方法

List<Integer> list2 = data.stream().distinct().collect(Collectors.toList());
结果:[3, 4, 8, 16, 19, 27, 23, 99, 15, 5, 232, 56]

sorted方法

1、自然升序

List<Integer> list3 = data.stream().sorted().collect(Collectors.toList());

2、自然序降

List<Integer> list4 = data.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

3、Comparator 自定义升序

List<Integer> list5 = data.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());

4、Comparator 自定义降序

List<Integer> list6 = data.stream().sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList());
结果:[3, 4, 5, 8, 8, 15, 16, 19, 23, 27, 56, 99, 232]
[232, 99, 56, 27, 23, 19, 16, 15, 8, 8, 5, 4, 3]
[3, 4, 5, 8, 8, 15, 16, 19, 23, 27, 56, 99, 232]
[232, 99, 56, 27, 23, 19, 16, 15, 8, 8, 5, 4, 3]

聚合

1、max方法

Integer maxItem = data.stream().max(Integer::compareTo).get();	

2、min方法

Integer minItem = data.stream().min(Integer::compareTo).get();

anyMatch方法

可以判定集合中是否还有匹配的元素

boolean b = data.parallelStream().allMatch(i -> i > 80);

allMatch方法

存在返回true

boolean all = data.parallelStream().allMatch(i -> i > 100);

noneMatch方法

不存在返回true

boolean none = data.parallelStream().noneMatch(i -> i > 100);

reduce方法

将流中的元素进行进一步计算的方法

1、求和

Integer sum1 = data.stream().reduce(Integer::sum).get();

2、对元素长度进行求和

Integer sum2 = data.stream().map(Objects::toString).mapToInt(String::length).sum();

收集到List中

List<Integer> list7 = data.stream().collect(Collectors.toList());

收集到Set中

Set<Integer> set = data.stream().collect(Collectors.toSet());
TreeSet<Integer> treeSet = data.stream().collect(Collectors.toCollection(TreeSet::new));

joining()

1、字符串连接

String str = afterString.stream().collect(Collectors.joining());

2、当流中的元素不是字符串时,需要先将流转成字符串流再进行拼接。

String str1 = data.stream().map(String::valueOf).collect(Collectors.joining(","));

收集聚合(总和、平均值、最大值、最小值)

int sum3 = data.stream().collect(Collectors.summingInt(Integer::intValue));
Double ave = data.stream().collect(Collectors.averagingInt(Integer::intValue));
Integer max = data.stream().collect(Collectors.maxBy(Integer::compare)).get();
Integer min = data.stream().collect(Collectors.minBy(Integer::compare)).get();

System.out.println("sum:" + sum3 + ",ave:" + ave + ",max:" + max + ",min:" + min);
结果:sum:515,ave:39.61538461538461,max:232,min:3

一次性收集流中的结果(总和、平均值、最大值、最小值)

IntSummaryStatistics summaryStatistics = data.stream().collect(Collectors.summarizingInt(Integer::intValue));
结果:IntSummaryStatistics{count=13, sum=515, min=3, average=39.615385, max=232}

集合转Map

Map<Integer, String> map = demos.stream().collect(Collectors.toMap(Demo::getId, Demo::getName));

当出现键冲突时只保留一个并且是保留已经存在的值时

Map<Integer, Demo> map1 = demos.stream().collect(Collectors.toMap(Demo::getId, Function.identity(), (nowValue, newValue) -> nowValue));

如果想指定生成的Map类型,则还需要第三个参数

TreeMap<Integer, Demo> roomTreeMap = demos.stream().collect(Collectors.toMap(Demo::getId, Function.identity(), (nowValue, newValue) -> newValue, TreeMap::new));

分组

Map<Integer, List<Demo>> groupMap = demos.stream().collect(Collectors.groupingBy(Demo::getAge));
结果:
{
20=[Demo(id=4, name=DDD, age=20)],
21=[Demo(id=2, name=BBB, age=21), Demo(id=5, name=EEE, age=21)],
24=[Demo(id=3, name=CCC, age=24)],
12=[Demo(id=1, name=AAA, age=12)]
}

分片

当分类函数是一个返回布尔值的函数时,流元素会被分为两组列表:一组是返回true的元素集合,另一组是返回false的元素集合。

Map<Boolean, List<Demo>> partitionMap = demos.stream().collect(Collectors.partitioningBy(d -> d.getAge() == 21));
结果:
{
false=[Demo(id=1, name=AAA, age=12), Demo(id=3, name=CCC, age=24), Demo(id=4, name=DDD, age=20)],
true=[Demo(id=2, name=BBB, age=21), Demo(id=5, name=EEE, age=21)]
}

分组统计

1、统计个数

Map<Integer, Long> countMap = demos.stream().collect(Collectors.groupingBy(Demo::getAge, Collectors.counting()));

2、计算总和

Map<Integer, Integer> sumMap = demos.stream().collect(Collectors.groupingBy(Demo::getAge, Collectors.summingInt(Demo::getAge)));

3、计算最大值

Map<String, Optional<Demo>> maxMap = demos.stream().collect(Collectors.groupingBy(Demo::getName, Collectors.maxBy(Comparator.comparing(Demo::getAge))));

4、计算最小值

Map<String, Optional<Demo>> minMap = demos.stream().collect(Collectors.groupingBy(Demo::getName, Collectors.minBy(Comparator.comparing(Demo::getAge))));

5、总和、平均值、总数、最大值、最小值

Map<String, IntSummaryStatistics> summaryStatisticsMap = demos.stream().collect(Collectors.groupingBy(Demo::getName, Collectors.summarizingInt(Demo::getAge)));
结果:
{
AAA=IntSummaryStatistics{count=1, sum=12, min=12, average=12.000000, max=12},
CCC=IntSummaryStatistics{count=1, sum=24, min=24, average=24.000000, max=24},
BBB=IntSummaryStatistics{count=1, sum=21, min=21, average=21.000000, max=21},
EEE=IntSummaryStatistics{count=1, sum=21, min=21, average=21.000000, max=21},
DDD=IntSummaryStatistics{count=1, sum=20, min=20, average=20.000000, max=20}
}

多级分组

Map<String, Map<Integer, List<Demo>>> multistageMap = demos.stream().collect(Collectors.groupingBy(Demo::getName, Collectors.groupingBy(Demo::getAge)));
结果:
{
"AAA":{
12:[{"age":12,"id":1,"name":"AAA"}]
},
"CCC":{
24:[{"age":24,"id":3,"name":"CCC"}]
},
"BBB":{
21:[{"age":21,"id":2,"name":"BBB"}]
},
"EEE":{
21:[{"age":21,"id":5,"name":"EEE"}]
},
"DDD":{
20:[{"age":20,"id":4,"name":"DDD"}]
}
}

以上列子测试数据

List<Integer> data = Arrays.asList(3,4,8,16,19,27,23,99,15,8,5,232,56);

Integer[] arr = new Integer[]{3, 4, 8, 16, 19, 27, 23, 99, 76, 232, 33, 96};

// --------------------------------------------

@Data
@Builder
class Demo {
private Integer id;
private String name;
private Integer age;
}
List<Demo> demos = Arrays.asList(
Demo.builder().id(1).name("AAA").age(12).build(),
Demo.builder().id(2).name("BBB").age(21).build(),
Demo.builder().id(3).name("CCC").age(24).build(),
Demo.builder().id(4).name("DDD").age(20).build(),
Demo.builder().id(5).name("EEE").age(21).build());

二、日期时间 API

当前日期

// 当前日期(yyyy-MM-dd)

LocalDate newDate = LocalDate.now();

当前时间

// 当前时间(HH:mm:ss)

LocalTime newTime = LocalTime.now();

当前日期时间

// 当前日期(yyyy-MM-dd HH:mm:ss)

LocalDateTime newDateTime = LocalDateTime.now();

计算时间或日期

1、获取过去n天或未来n天的日期 (plus()、minus())

// 获取7天前的日期

LocalDate date7_1 = newDate.minusDays(7);

// 获取7天后的日期

LocalDate date7_2 = newDate.plusDays(7);

2、获取过去n月或未来n月的日期

// 获取7个月前的日期

LocalDate month7_1 = newDate.minusMonths(7);

// 获取7个月后的日期

LocalDate month7_2 = newDate.plusMonths(7);

备注:在java.time.LocalTime和java.time.LocalDateTime中也有对应的plus()和minus()方法。

日期比较

日期比较(isBefore()、isAfter()),返回true或false

LocalDate newD = LocalDate.now();
LocalDate lsatD = newD.plusDays(1);

if (lsatD.isAfter(newD)) {
System.out.println("newD小于lsatD");
} else {
System.out.println("newD大于lsatD");
}

if (lsatD.isBefore(newD)) {
System.out.println("newD大于lsatD");
} else {
System.out.println("newD小于lsatD");
}

日期时间格式化

// 日期格式化为(yyyy-MM-dd)

String date1 = newDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

// 日期格式化为(yyyyMMdd)

String date2 = newDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));

// 日期格式化为(yyyy-MM)

String date3 = newDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));

// 日期格式化为(yyyy-MM-dd HH:mm:ss)

String date4 = newDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

获取基本属性

// 年份

int year = newDate.getYear();

// 月份

int month = newDate.getMonthValue();

// 星期

int week = newDate.getDayOfWeek().getValue()

计算两个日期之间相差多少天

LocalDate localDate1 = LocalDate.of(2019, 8, 1);
LocalDate localDate2 = LocalDate.of(2019, 8, 20);

// 相差天数为
int num = (int) (localDate2.toEpochDay() - localDate1.toEpochDay());

// Period
Period period = Period.between(localDate1,localDate2);

// 相差多少年
period.getYears()

// 相差多少月
period.getMonths()

// 相差多少日 (一年内的)
period.getDays()

// 逻辑日历的天数
long days = ChronoUnit.DAYS.between(localDate1, localDate2);

Period中时间区间如果是2年1个月15天。那么通过getDays()方法获得就是第三个存储15天。而不是2年1个月15天总共有多少天。

想要逻辑日历的天数,使用DAYS.between()方法。

字符串转日期

LocalDate date = LocalDate.parse("2021-08-01");

获取某个时间在这个月的开始时间和结束时间

// 开始时间
LocalDate fistDate = LocalDate.parse("2019-08-28").with(TemporalAdjusters.firstDayOfMonth());

// 结束时间
LocalDate lastDate = LocalDate.parse("2019-08-28").with(TemporalAdjusters.lastDayOfMonth());

获取星期

LocalDate.parse("2021-08-28").getDayOfWeek()

判断是否是闰年

LocalDate.now().isLeapYear()

每天的开始时间、结束时间

// 开始时间
LocalTime.MIN

// 结束时间
LocalTime.MAX

获取毫秒值

Instant.now().toEpochMilli()

字符串转LocalDateTime

LocalDateTime.parse("2019-05-14 21:15:30.555", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))

LocalDateTime转字符串

DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").format(LocalDateTime.now())

Java8 常用 API


原文始发于微信公众号(全栈客):Java8 常用 API

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/162672.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!