您的位置:首页 > 编程语言 > Java开发

javaSE基础知识——day20 1.8新增日期API,Lambda表达式的方法构造引用,Stream流,筛选切片,映射,排序

2019-08-04 17:32 337 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/lalaMarry/article/details/98440296

JDK1.8 新增的日期时间API

? LocalDate、 LocalTime、 LocalDateTime类的实例是不可变的对象,
? 分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。
? 它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。
? 注: ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法
? 这些新增的日期时间API都在 java.time包下

获取方法

  • 方式1通过静态方法 now();
    例如:LocalDateTime ldt = LocalDateTime.now();

  • 方式2通过静态方法of()方法参数可以指定年月日时分秒
    例如:LocalDateTime of = LocalDateTime.of(2018, 12, 30, 20, 20, 20);

  • 常用方法
    1.获取相关的get系类的方法:
    lad.getYear()获得年
    lad.getMinute()获得分钟
    lad.getHour();获得时间
    getDayOfMonth获得月中天数(1-31)
    getDayOfYear获得年中的天数(1-360)
    getDayOfWeak获得星期几(返回一个 DayOfWeek枚举值)
    getMonth获得月份, 返回一个 Month 枚举值
    getMonthValue获得月份(1-12)
    getYear获得年份

package day20190804.新增的时间日期API;

import java.time.*;

/**
* @description:
* @author: @李小白
* @create: 2019-08-04 10:09
*/
public class Demo01时间日期和get方法 {
public static void main(String[] args) {
System.out.println("=============now=获得当前日期===============");
//now  获得当前日期和时间
LocalDate now = LocalDate.now();//获得当前日期
LocalTime now1 = LocalTime.now();//获得当前时间
LocalDateTime now2 = LocalDateTime.now();//获得当前日期和时间
System.out.println(now);
System.out.println(now1);
System.out.println(now2);

System.out.println("============of=可以指定日期==============");

//可以指定日期
LocalDate of = LocalDate.of(2018, 10, 10);
System.out.println(of);

LocalDateTime of1 = LocalDateTime.of(2018, 10, 10, 12, 12, 12);
System.out.println(of1);

System.out.println("===============get方法=============");

System.out.println(now2.getYear());
System.out.println(now2.getHour());
System.out.println(now2.getMinute());

System.out.println(now2.getDayOfMonth());
System.out.println(now2.getDayOfWeek());
System.out.println(now2.getDayOfYear());

System.out.println(now2.getMonth());
System.out.println(now2.getMonthValue());
}
}

2.格式化日期字符串的方法:format()
例如:String yyyy = ldt.format(DateTimeFormatter.ofPattern(“yyyy”));
3.时间日期转换的方法:toLocalDate();toLocalTime();
例如:LocalDate localDate = ldt.toLocalDate();
例如:LocalTime localTime = ldt.toLocalTime();
4.判断的方法
isAfter()判断一个日期是否在指定日期之后
isBefore()判断一个日期是否在指定日期之前
isEqual(); 判断两个日期是否相同
isLeapYear()判断是否是闰年注意是LocalDate类中的方法
例如: boolean after = ldt.isAfter(LocalDateTime.of(2024, 1, 1, 2, 3));
例如 boolean b= LocalDate.now().isLeapYear();

package day20190804.新增的时间日期API;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
* @description:
* @author: @李小白
* @create: 2019-08-04 10:37
*/
public class Demo02格式化日期转换判断日期 {
public static void main(String[] args) {

LocalDateTime now = LocalDateTime.now();
LocalDate now1 = LocalDate.now();
LocalTime now2 = LocalTime.now();

LocalDateTime of = LocalDateTime.of(2018,11,4,11,11,11);

System.out.println("===============格式化日期==============");
//自己指定日期格式
String format = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
System.out.println(format);
System.out.println("=================时间日期转换的方法===================");
LocalDate localDate = now.toLocalDate();
LocalTime localTime = now.toLocalTime();
System.out.println("==================判断日期=====================");
//两个日期对比前后
System.out.println(now.isAfter(of));//是否在之前
System.out.println(now.isBefore(of));//是否在之后
System.out.println(now.isEqual(of));//是否相等
System.out.println(now1.isLeapYear());//是否是瑞年

}
}

5.解析的静态方法:parse(“2007-12-03T10:15:30”);
paser() 将一个日期字符串解析成日期对象,注意字符串日期的写法的格式要正确,否则解析失败

例如:LocalDateTime parse = LocalDateTime.parse(“2007-12-03T10:15:30”);

按照我们指定的格式去解析,格式要对应,否则报错
LocalDateTime ldt4 = LocalDateTime.now();
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);
LocalDateTime.parse(“2018-01-21 20:30:36”, formatter2);

package day20190804.新增的时间日期API;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
* @description:
* @author: @李小白
* @create: 2019-08-04 10:57
*/
public class Demo03解析日期 {
public static void main(String[] args) {

//        String str="yyyy-MM-ddTHH:mm:ss";
System.out.println("-------按照默认的形式解析------");
LocalDateTime parse = LocalDateTime.parse("2007-12-03T10:15:30");
System.out.println(parse);
System.out.println("-----按照我们指定的格式进行解析------");
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");

LocalDateTime parse1 = LocalDateTime.parse("2007年12月05日 10时15分30秒", dateTimeFormatter);
System.out.println(parse1);
}
}

6.添加年月日,时分秒方法pluse 系列,会返回一新的对象
LocalDateTime localDateTime = ldt.plusYears(1);
LocalDateTime localDateTime1 = ldt.plusMonths(3);
LocalDateTime localDateTime2=ldt.plusHours(10);
7.减去年月日,时分秒的方法minus系列方法,会返回一个新的对象
例如:LocalDateTime localDateTime2 = ldt.minusYears(8);
8.指定年月日时分秒的方法 with系列的方法,都会返回一个新的对象
例如 LocalDateTime localDateTime3 = ldt.withYear(1998);
//获取这个月的第几个星期几是几号,比如 TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY) 代表的意思是这个月的第二个星期五是几号
// TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY)
LocalDateTime with1 = now.with(TemporalAdjusters.dayOfWeekInMonth(2,DayOfWeek.FRIDAY));

package day20190804.新增的时间日期API;

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;

/**
* @description: 添加和减去年月日
* @author: @李小白
* @create: 2019-08-04 11:18
*/
public class Demo04添加年月日pluse减去with {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println("==============添加pluse系列=========");
System.out.println(now.plusDays(2));//在现在的基础上+2天
System.out.println(now.plusMonths(3));//在现在的基础上+3个月
System.out.println(now.plusYears(5));//在现在的基础上+5年
System.out.println("==========减少with系列============");
//指定日期
System.out.println(now.withHour(3));//减少到3点
System.out.println(now.withYear(2005));//减少
7ff7
到2005年
System.out.println(now.withDayOfMonth(2));
//指定日期,第一天,最后一天
System.out.println(now.with(TemporalAdjusters.firstDayOfMonth()));//这个月的第一天
System.out.println(now.with(TemporalAdjusters.firstDayOfNextMonth()));//下个月的第一天
System.out.println(now.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)));//指定下周五
System.out.println(now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));//指定下周日
System.out.println(now.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)));//指定下周六

}
}

DInstant 时间戳类从1970-01-01 00:00:00 截止到当前时间的毫秒值

1获取对象的方法 now(),默认是美国时间和我们相差8小时
Instant ins = Instant.now();
2.在Instant中设置偏移量的方法:atOffset() 设置偏移量
OffsetDateTime time = ins.atOffset(ZoneOffset.ofHours(8));
System.out.println(time);

3.获取系统本地默认时区时间的方法atZone()
ZonedDateTime zonedDateTime = ins.atZone(ZoneId.systemDefault());
System.out.println(zonedDateTime);

4.get系列的方法
getEpochSecond() 获取从1970-01-01 00:00:00到当前时间的秒值
toEpochMilli();获取从1970-01-01 00:00:00到当前时间的毫秒值
getNano()方法是把获取到的当前时间的秒数 换算成纳秒
long epochSecond = ins.getEpochSecond();//获取从1970-01-01 00:00:00到当前时间的秒值
getNano()方法是把获取到的当前时间的豪秒数 换算成纳秒 比如当前时间是2018-01-01 14:00:20:30
那就把30豪秒换算成纳秒 int nano = ins.getNano();

  1. ofEpochSecond()方法 给计算机元年增加秒数
    ofEpochMilli() 给计算机元年增加毫秒数
    例如 Instant instant = Instant.ofEpochSecond(5);
    System.out.println(instant);
    单位换算
    0.1 毫秒 = 10 的5次方纳秒 = 100000 纳秒
    1 毫秒 = 1000 微妙 = 1000000 纳秒
package day20190804.新增的时间日期API;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Set;

/**
* @description: DInstant时间戳类,当前时间,偏移量时区,时间设置,get方法
* @author: @李小白
* @create: 2019-08-04 11:40
*/
public class Demo05Instant时间戳类当前偏移量get {
public static void main(String[] args) {
Instant ins = Instant.now();

System.out.println(ins);//输出来的时间是美国时间
System.out.println("===============获取自己的时区==============");
System.out.println(ins.atOffset(ZoneOffset.ofHours(8)));//设置我们自己的东八区
System.out.println(ins.atZone(ZoneId.systemDefault()));//获取系统默认的时区

System.out.println("--------通过检索亚洲获取时区-------");
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
for (String availableZoneId : availableZoneIds) {
if(availableZoneId.startsWith("Asia")){
System.out.println(availableZoneId);
}

}
System.out.println("=========get方法=to=of============");
System.out.println(ins.getEpochSecond());//获取当前时间的的秒值
System.out.println(ins.toEpochMilli());//获取当前时间的毫秒值
System.out.println(Instant.ofEpochSecond(60 * 60));//给计算机元年增加秒数
System.out.println(Instant.ofEpochMilli(1000 * 60 * 06));//给计算机原年增加毫秒数
}
}

Duration : 用于计算两个“时间”间隔的类

Period : 用于计算两个“日期”间隔的类

Duration类中静态方法between()
Instant start = Instant.now();
for(int i=0;i<1000L;i++){
System.out.println(“循环内容”);
}
Instant end = Instant.now();
静态方法:between() 计算两个时间的间隔,默认是秒
Duration between = Durati’on.between(start, end);
Duration中的toMillis()方法:将秒转成毫秒
System.out.println(between.toMillis());

Period类 中的静态方法between()
计算两个日期之间的间隔
LocalDate s = LocalDate.of(1985, 03, 05);
LocalDate now = LocalDate.now();
Period be = Period.between(s, now);
System.out.println(be.getYears());间隔了多少年
System.out.println(be.getMonths());间隔了多少月
System.out.println(be.getDays());间隔多少天

package day20190804.新增的时间日期API;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.Period;

/**
* @description:duration period
* @author: @李小白
* @create: 2019-08-04 12:01
*/
public class Demo06计算时间间隔日期间隔 {
public static void main(String[] args) {
System.out.println("=============计算时间间隔=duration==========");
Instant str = Instant.now();
for (int i = 0; i < 10000; i++) {
System.out.println(' ');
}
Instant end = Instant.now();
Duration duration = Duration.between(str, end);
System.out.println(duration.toMillis());//将时间间隔转成毫秒值输出

System.out.println("==========计算日期间隔=preiod===========");

LocalDate now = LocalDate.now();
LocalDate of = LocalDate.of(2016,11,4);
Period between = Period.between(of, now);
System.out.println(between.getYears());
System.out.println(between.getMonths());
System.out.println(between.getDays());
}
}

TemporalAdjuster : 时间校正器,是个接口

例如:
LocalDate now = LocalDate.now();
System.out.println(now);
1 使用TemporalAdjusters自带的常量来设置日期
LocalDate with = now.with(TemporalAdjusters.lastDayOfYear());
System.out.println(with);
2 采用TemporalAdjusters中的next方法来指定日期
LocalDate date = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(date);
例如:TemporalAdjusters.next(DayOfWeek.SUNDAY) 本周的星期天
例如:TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY) 下一周的星期一
3 采用自定义的方式来指定日期 比如指定下个工作日
LocalDateTime ldt = LocalDateTime.now();
LocalDateTime workDay = ldt.with(new TemporalAdjuster() {
@Override
public Temporal adjustInto(Temporal temporal) {
//向下转型
LocalDateTime ld = (LocalDateTime) temporal;
//获取这周的星期几
DayOfWeek dayOfWeek = ld.getDayOfWeek();
if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
return ld.plusDays(3);//如果这天是星期五,那下个工做日就加3天
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
return ld.plusDays(2);//如果这天是星期六,那下个工做日就加2天
} else {
//其他就加一天
return ld.plusDays(1);
}
}
});

System.out.println(workDay);
package day20190804.新增的时间日期API;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;

/**
* @description: 指定日期,可以自定义指定日期
* @author: @李小白
* @create: 2019-08-04 13:38
*/
public class Demo07TemporalAdjusters {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime with = now.with(TemporalAdjusters.firstDayOfNextMonth());//下个月的第一天
System.out.println(with);

LocalDateTime with1 = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));//本周的周一,如果时间过去了,就会自定调节成下周的周一
System.out.println(with1);
LocalDateTime with2 = now.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
System.out.println(with2);//下周的周一

System.out.println("===========采用自定义的方式指定日期=========");
// 3 采用自定义的方式来指定日期 比如指定下个工作日
//今天如果时星期五 下个工作日 +3
//今天如果时星期六 下个工作日 +2
//其他 +1

LocalDateTime newDate = now.with(new TemporalAdjuster() {
@Override
public Temporal adjustInto(Temporal temporal) {
// temporal 当前日期
//向下转型
LocalDate localDate= (LocalDate) temporal;
//后期当前日期时星期几
DayOfWeek dayOfWeek = localDate.getDayOfWeek();

if(dayOfWeek.equals(DayOfWeek.FRIDAY)){
LocalDate localDate1 = localDate.plusDays(3);
return localDate1;
}else if(dayOfWeek.equals(DayOfWeek.SATURDAY)){
LocalDate localDate1 = localDate.plusDays(2);
return localDate1;
}else{
LocalDate localDate1 = localDate.plusDays(1);
return localDate1;
}
}
});
System.out.println(newDate);

}
}

DateTimeFormatter :解析和格式化日期或时间的类

方法有5种

方法一

1.获取对象的方式,通过静态方法ofPattern(“yyyy-MM-dd”)
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(“yyyy-MM-dd”);
LocalDateTime now = LocalDateTime.now();
2.format()方法把一个日期对象的默认格式 格式化成指定的格式
String format1 = dateFormat.format(now);
System.out.println(format1);
3.格式化日期 方式2使用日期类中的format方法 传入一个日期格式化类对象

LocalDateTime now1 = LocalDateTime.now();
使用日期类中的format方法 传入一个日期格式化类对象
使用DateTimeFormatter中提供好的日期格式常量
now1.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);

4.使用自定义的日期格式格式化字符串
DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);//自定义一个日期格式
String time = now1.format(timeFormat);
System.out.println(time);

  1. 把一个日期字符串转成日期对象使用日期类中的parse方法传入一个日期字符串,传入对应的日期格式化类
    DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(“yyyy-MM-dd”);
    LocalDateTime parse = LocalDateTime.parse(time, timeFormat);
    System.out.println(parse);
package day20190804.新增的时间日期API;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

import static java.time.format.DateTimeFormatter.*;

/**
* @description:
* @author: @李小白
* @create: 2019-08-04 13:52
*/
public class Demo08DataTimeFormat的5种方法 {
public static void main(String[] args) {

DateTimeFormatter dateTimeFormatter = ofPattern("yyyy年MM月dd");

System.out.println("===============方式一=============");
//方式1 可以使用DateTimeFormatter 他的format()
LocalDate now = LocalDate.now();
String format = dateTimeFormatter.format(now);
System.out.println(format);
System.out.println("============方式二===============");
//方式2  使用 LocalDate 的format方法
String format1 = now.format(dateTimeFormatter);
System.out.println(format1);
System.out.println();
System.out.println("============方式三============");
//使用自带的格式
String format2 = now.format(DateTimeFormatter.ISO_DATE);
System.out.println(format2);
//把字符串解析成日期
String str="2019-09-04";
LocalDate parse = LocalDate.parse(str);
System.out.println(parse);

String str2="2019年11月11日";
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
LocalDate parse1 = LocalDate.parse(str2, dateTimeFormatter1);
System.out.println(parse1);
}
}

ZonedDate,ZonedTime、ZonedDateTime : 带时区的时间或日期

? 用法和 LocalDate、 LocalTime、 LocalDateTime 一样 只不过ZonedDate,ZonedTime、ZonedDateTime 这三个带有当前系统的默认时区

ZoneID 世界时区类

1.获取世界各个地方的时区的集合 的方法getAvailableZoneIds()
? 使用ZoneID中的静态方法getAvailableZoneIds();来获取
? 例如:Set availableZoneIds = ZoneId.getAvailableZoneIds();
? 2.获取系统默认时区的ID
? ZoneId zoneId = ZoneId.systemDefault(); //Asia/Shanghai
? 3.获取带有时区的日期时间对象
? //创建日期对象
? LocalDateTime now = LocalDateTime.now();
? //获取不同国家的日期时间根据各个地区的时区ID名创建对象
? ZoneId timeID = ZoneId.of(“Asia/Shanghai”);
? //根据时区ID获取带有时区的日期时间对象
? ZonedDateTime time = now.atZone(timeID);
? System.out.println(time);
? //方式2 通过时区ID 获取日期对象

package day20190804.新增的时间日期API;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Set;

/**
* @description: 获取世界各个地方的时间ID、
* @author: @李小白
* @create: 2019-08-04 14:12
*/
public class Demo09获取时间ID {
public static void main(String[] args) {
//##ZonedDate, ZonedTime、ZonedDateTime :带时区的时间或日期
//
//        ? 用法和 LocalDate、LocalTime、LocalDateTime 一样 只不过ZonedDate, ZonedTime、ZonedDateTime 这三个带有当前系统的默认时区
//LocalDateTime
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);

// ZoneID 世界时区类
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);

Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();

}
}

JDK1.8的新特性之Lambda表达式的学习

概念:Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。

package day20190804.lambda表达式;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
* @description: lambda
* @author: @李小白
* @create: 2019-08-04 14:55
*/
public class Demo01第一个lambda表达式 {

public static void main(String[] args) {
//JDK1.8 引入一种语法 Lambda 表达式 ,你 可以理解为是匿名内部类的一种简写方式,但是有条件
// Lambda表达式要用到 -> 箭头符号
// 以 -> 箭头符号 分为左右两半
// 箭头左边是重写接口中抽象方法的参数列表 ()->
// 箭头右边是对接口中抽象方法的重写逻辑 ->重写逻辑
List<Integer> list = Arrays.asList(10, 23, 45, 67, 89);
//匿名内部类的写法
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return a-b;
}
});

//简写的lambda表达式
//第一步 简写
list.sort((Integer x,Integer y)->{return x-y;});
//第二步 简写
list.sort((x,y)->{return  x-y;});
//第三步简写:如果你对方法实现逻辑只有一行,可以省略{} 和  return
//但是如果,你对接口中的抽象方法的实现逻辑不是一行,就不能省略{}和return
//第三步  简写
list.sort((x,y)->x-y);

}
}

什么是函数式接口

函数式接口的定义是: 只包含一个抽象方法的接口

  • Java中提供的4大核心函数式接口
    函数式接口 参数类型 返回类型 用途
    1.Consumer
    消费型接口 T void 对类型为T的对象应用操作,包含方法:void accept(T t)
    2.Supplier
    供给型接口 无 T 返回类型为T的对象,包含方法: T get();
    3.Function<T, R>
    函数型接口T R 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法: R apply(T t);
    4.Predicate
    断言型接口T boolean 确定类型为T的对象是否满足某约束,并返回boolean 值。包含方法boolean test(T t);
package day20190804.lambda表达式;

/**
* @description: 函数式接口
* @author: @李小白
* @create: 2019-08-04 15:04
*/
public class Demo02函数式接口 {

public static void main(String[] args) {
Demo02show方法 demo02 = new Demo02show方法() {
@Override
public void show() {
System.out.println(100);
}
};
//lamble表达式
//使用Lambda表达式简写
Demo02show方法 demos02 = ()-> System.out.println(100);
//使用可变参数进行写lambda表达式
myTest(()->System.out.println(100));
}
private static void myTest(Demo02show方法 my) {
my.show();
}
}
package day20190804.lambda表达式;

/**
* @description:
* @author: @李小白
* @create: 2019-08-04 15:05
*/
public interface Demo02show方法 {
void show();
}
package day20190804.lambda表达式;

import java.util.function.Consumer;
import java.util.function.Supplier;

/**
* @description: 函数式接口
* @author: @李小白
* @create: 2019-08-04 15:17
*/
public class Demo03java给我们提供的函数式接口 {
public static void main(String[] args) {
//Java 给我们提供了一些函数式接口
Consumer<Integer> con= integer -> System.out.println(integer);

// Consumer<Integer> con2=b-> System.out.println(b);

Supplier<String> supplier = () -> "abc";
}
}

方法引用与构造器引用

  • 方法引用?
    方法引用其实是Lambda表达式的另一种写法,当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用.
  • 注意:
    实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!
  • 方法引用
    使用操作符 “ ::” 将方法名和对象或类的名字分隔开来。
  • 如下三种主要使用情况:
    对象::实例方法
    类::静态方法
    类::实例方法
package day20190804.lambda表达式;

import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

/**
* @description: 方法引用
* @author: @李小白
* @create: 2019-08-04 15:40
*/
public class Demo04方法引用 {
public static void main(String[] args) {
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
consumer.accept("哈哈");

Consumer<String> consumer2= x-> System.out.println(x);
consumer2.accept("呵呵");

//再次对Lambda表达式简写
//这种简写叫做方法引用
//你对接口中的抽象方法的实现逻辑中调用的这个方法,跟接口中的这个方法的返回值和形参列表一致的化,就可以用方法引用再次简写
Consumer<String> consumer3=System.out::println;

consumer3.accept("哈哈哈哈哈");

System.out.println("--------------------------------");
Function<String, Integer> function = new Function<String, Integer>() {
@Override
public Integer apply(String s) {//一个参数,一个返回值
int i = Integer.parseInt(s);//一个参数,一个返回值
return i;
}
};

Function<String, Integer> function2 =(x)->Integer.parseInt(x);

Function<String, Integer> function3=Integer::parseInt;

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

BiFunction<Double, Double, Double> biFunction = new BiFunction<Double, Double, Double>() {
@Override
public Double apply(Double aDouble, Double aDouble2) {
Math.max(aDouble, aDouble2);
return null;
}
};

BiFunction<Double, Double, Double> biFunction2=(a,b)->Math.max(a,b);

//方法引用
BiFunction<Double, Double, Double> biFunction3=Math::max;

System.out.println("--------------------------");
Function<Integer, String> function1 = new Function<Integer, String>() {
@Override
public String apply(Integer s) {
String s1 = String.valueOf(s);
return s1;
}
};

Function<Integer, String> function4=String::valueOf;
}
}

构造器引用

public class MyTest {
public static void main(String[] args) {
//JDK1.8时间日期API
// LocalDate
//  LocalDateTime
//  LocalTime
// DateTimeFormatter
// Instant
// Duration
// Period
// ZoneId

// Lambda     接口中抽象方法的参数列表->你对抽象方法的实现逻辑
//函数式接口,才支持Lambda   @FunctionalInterface 注解 是一个函数式样接口
// 方法引用:你再重写接口中的方法时,不经意间,调用了一个方法,这个方法的形参和返回值,正好能跟这个抽象方法的形参和返回值,对应上,就可以使用方法引用简写
//构造引用

Supplier<MyClass> supplier = new Supplier<MyClass>() {
@Override
public MyClass get() {
return new MyClass();
}
};

Supplier<MyClass> supplier2 = () -> new MyClass();

//构造引用
Supplier<MyClass> supplier3 = MyClass::new;

Function<String, MyClass> function = new Function<String, MyClass>() {

@Override
public MyClass apply(String s) {
return new MyClass(s);
}
};

MyClass zhangsan = function.apply("zhangsan");

Function<String, MyClass> function2 =(s)->new MyClass(s);

Function<String, MyClass> function3 =MyClass::new;
}
}

Stream API(java.util.stream.*)

  • 概念:Stream API 提供了一种高效且易于使用的处理数据的方式。
    Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。
    使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。

流(Stream) 到底是什么呢?

是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列

集合讲的是数据,流讲的是计算!

注意:

1.Stream流不会存储元素
2.Stream流不会改变原对象,他们会返回一个新的流
3.Stream流是演示操作,到需要结果的时候才执行

Steam流操作的三个步骤

1.创建一个Stream数据源
2.中间操作:对数据源的数据进行处理
3终止操作:执行中间操作链并产生结果

创建Stream流的4种方式

1.Java8 中的 Collection 接口被扩展,提供了
两个获取流的方法:
 default Stream stream() : 返回一个顺序流
 default Stream parallelStream() : 返回一个并行流
2.Java8 中的 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.由值创建流,可以使用静态方法 Stream.of(), 通过显示值创建一个流。它可以接收任意数量的参数。
 public static Stream of(T… values) : 返回一个流
4.由函数创建流:创建无限流可以使用静态方法 Stream.iterate()和Stream.generate(), 创建无限流。
public static Stream iterate(final T seed, finalUnaryOperator f) 迭代
public static Stream generate(Supplier s) 生成

package day20190804.Stream流;

import java.util.Arrays;
import java.util.List;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;

/**
* @description:创建Stream流的5中方式
* @author: @李小白
* @create: 2019-08-04 16:04
*/
public class Demo01的5个方式 {
public static void main(String[] args) {
//方式一  集合中的一个方法Stream
List<Integer> list = Arrays.asList(12, 34, 56, 78, 89);
Stream<Integer> stream = list.stream();
//方式二: Arrays中的一个静态方法
Stream<Integer> stream1 = Arrays.stream(new Integer[]{12, 34, 35, 67, 98});
//方式三:Stream中的静态方法of
Stream<Integer> integerStream = Stream.of(32, 34, 67, 34, 65, 87);
//方式四:创建一个无限久流
Stream<Integer> iterate = Stream.iterate(1, new UnaryOperator<Integer>() {
@Override
public Integer apply(Integer integer) {
return integer + 1;
}
});
//中间操作执行完了之后,返回一个持有结果的新流
Stream<Integer> limit = iterate.limit(9);//只要其中的9个
//没有进行终止操作中间环节不执行,主要体现的是一种延迟的思想
limit.forEach(System.out::println);

//创建出一个无限流
Stream.generate(()->Math.random()).limit(5).forEach(System.out::println);
}
}

Stream流的中间操作

多个中间操作可以连成一个流水线,中间操作不触发终止操作,则不会执行任何的处理

在终止行擦操作一次性处理的现象,被称为:“惰性求值”

1.筛选与切片filter()distinct()

filter(Predicate p) 过滤 接收 Lambda , 从流中排除某些元素。
distinct() 去重,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
limit(long maxSize) 截断流,使其元素不超过给定数量。
skip(long n)	    跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
package day20190804.Stream流;

public class Employee {

private int id; //员工的id
private String name; //员工的姓名
private int age; //员工的年龄
private double salary; //员工的工资
private Status status; //员工的状态

public Employee() {
}

public Employee(String name) {
this.name = name;
}

public Employee(String name, int age) {
this.name = name;
this.age = age;
}

public Employee(int id, String name, int age, double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}

public Employee(int id, String name, int age, double salary, Status status) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
this.status = status;
}

public Status getStatus() {
return status;
}

public void setStatus(Status status) {
this.status = status;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public double getSalary() {
return salary;
}

public void setSalary(double salary) {
this.salary = salary;
}

public String show() {
return "测试方法引用!";
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(salary);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (age != other.age)
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))
return false;
return true;
}

@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + ", status=" + status
+ "]";
}

//枚举
public enum Status {
FREE, //空闲
BUSY, //繁忙
VOCATION;//休假
}

}
package day20190804.Stream流;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
* @description: 筛选与切片
* @author: @李小白
* @create: 2019-08-04 16:25
*/
public class Demo02筛选与切片 {

public static  void main(String[] args) {
//1. 筛选与切片
//filter(Predicate p) 过滤 接收 Lambda ,从流中排除某些元素。
//distinct() 去重,通过流所生成元素的 hashCode () 和 equals () 去除重复元素
//limit( long maxSize)截断流,使其元素不超过给定数量。
//skip( long n)跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit (n) 互补

//        1. 创建 Stream
//        一个数据源(如:集合、数组),获取一个流
//2. 中间操作
//        一个中间操作链,对数据源的数据进行处理
//3. 终止操作(终端操作)
//        一个终止操作,执行中间操作链,并产生结果

List<Employee>  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)
);
System.out.println("================获取工作大于8000的员工==============");
//获取流
Stream<Employee> stream = emps.stream();
//中间操作
Stream<Employee> employeeStream = stream.filter(e -> e.getSalary() > 8000);
System.out.println(employeeStream);
//终止操作
employeeStream.forEach(System.out::println);
System.out.println("==========获取姓赵的员工===============");
//获得流
Stream<Employee> stream1 = emps.stream();
//中间操作
Stream<Employee>  name= stream1.filter(e -> e.getName().startsWith("赵"));
System.out.println(name);
//终止操作
name.forEach(System.out::println);
System.out.println("=========从头开始截取几个元素============");
List<Integer> list = Arrays.asList(12, 34,
8000
56, 67, 89, 90, 9);
Stream<Integer> limit = list.stream().limit(4);
System.out.println(limit);
System.out.println("=========从头开始跳过几个元素============");
List<Integer> list2 = Arrays.asList(12, 34, 56, 67, 89, 90, 9);
Stream<Integer> skip = list2.stream().skip(3);
System.out.println(skip);
}
}

2.映射

map(Function f)			接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatMap(Function f)		接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流.
mapToDouble(ToDoubleFunction f)	接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
mapToInt(ToIntFunction f)	接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。
mapToLong(ToLongFunction f)	接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。

案例一:把名字取出来

package day20190804.Stream流;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

/**
* @description:
* @author: @李小白
* @create: 2019-08-04 16:58
*/
public class Demo03映射 {
public static void main(String[] args) {
//2. 映射
//map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
//flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流.
//
List<Employee> 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)
);
System.out.println("=============把名字取出来==============");
//获取流
Stream<Employee> stream = emps.stream();
//中间操作
Stream<String> stringStream = stream.map(e -> e.getName());
System.out.println(stringStream);
//终止操作
stringStream.forEach(System.out::println);
System.out.println("=====把集合中的小写元素变成大写======");
List<String> strings = Arrays.asList("aaa", "bbb", "ccc");
Stream<String> stream1 = strings.stream();
stream1.map(new Function<String, String>() {
@Override
public String apply(String s) {
String s1 = s.toUpperCase();
return s1;
}
}).forEach(System.out::println);
}
}

案例二:把字符串截取成单独的字符

package day20190804.Stream流;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

/**
* @description: 把字符串截成字符放到流中
* @author: @李小白
* @create: 2019-08-04 17:11
*/
public class Demo04把字符串截成字放到流中 {
public static void main(String[] args) {
List<String> list = Arrays.asList("aaa", "bbb", "ccc");
Stream<String> stream = list.stream();
//中间操作
Stream<Stream<Character>> streamStream = stream.map(new Function<String, Stream<Character>>() {
@Override
public Stream<Character> apply(String s) {
Stream<Character> aChar = getChar(s);//抽出一个方法出来
return null;
}
});
//终止操作
streamStream.forEach(new Consumer<Stream<Character>>() {
@Override
public void accept(Stream<Character> characterStream) {
characterStream.forEach(System.out::println);
}
});

}
private static Stream<Character> getChar(String str) {
ArrayList<Character> characters = new ArrayList<>();
for (char ch : str.toCharArray()) {
characters.add(ch);
}
return characters.stream();
}
}

案例三:算阶乘

List<Integer> integers = Arrays.asList(10, 20, 30, 40);
Stream<Integer> stream = integers.stream();
Stream<Double> doubleStream = stream.map(new Function<Integer, Double>() {
@Override
public Double apply(Integer integer) {

return Math.pow(integer, 2);
}
});
doubleStream.forEach(System.out::println);
}

3.排序

sorted()	产生一个新流,其中按自然顺序排序   元素实现Compareble接口
sorted(Comparator comp)	产生一个新流,其中按比较器顺序排序  传入一个比较

**Stream 的终止操作
终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: