Java番外篇2——jdk8新特性
2021-7-15
若以色见我,以音声求我,是人行邪道,不能见如来
1、Lambda
1.1、无参无返回值
public class Test {
interface Print{
void print();
}
public static void main(String[] args) {
// Print print=new Print() {
// @Override
// public void print() {
// System.out.println("hello word!");
// }
// };
Print print=()-> System.out.println("hello word!");
print.print();
}
}
1.2、一个参数无返回值
public class Test {
interface Print{
void print(String str);
}
public static void main(String[] args) {
// Print print=new Print() {
// @Override
// public void print(String str) {
// System.out.println("hello word! "+str);
// }
// };
Print print=str-> System.out.println("hello word! "+str);
print.print("ruoye");
}
}
1.3、多个参数无返回值
public class Test {
interface Print{
void print(String str,String str1);
}
public static void main(String[] args) {
// Print print=new Print() {
// @Override
// public void print(String str,String str1); {
// System.out.println("hello word! "+str+str1);
// }
// };
Print print=(str,str1)-> System.out.println("hello word! "+str+str1);
print.print("ruoye","yoya");
}
}
1.4、多个参数有返回值(单句)
public class Test {
interface Print{
String print(String str,String str1);
}
public static void main(String[] args) {
Print print=(str,str1)-> str+str1;
System.out.println(print.print("ruoye", "yoya"));
}
}
1.4、多个参数有返回值(多句)
public class Test {
interface Print{
String print(String str,String str1);
}
public static void main(String[] args) {
Print print=(str,str1)-> {
System.out.println("hello word! "+str+str1);
return str+str1;
};
System.out.println(print.print("ruoye", "yoya"));
}
}
2、函数式接口(@FunctionalInterface)
- 该注解只能标记在"有且仅有一个抽象方法"的接口上
- JDK8接口中可以定义静态方法和默认方法(方法默认实现default),都不算是抽象方法
public class Test {
@FunctionalInterface
interface Print{
String print(String str,String str1);
}
public static void main(String[] args) {
Print print=(str,str1)-> {
System.out.println("hello word! "+str+str1);
return str+str1;
};
System.out.println(print.print("ruoye", "yoya"));
}
}
3、接口调整
方便接口扩展
jdk8之前接口只能有静态常量和抽象方法
jdk8后接口可以有默认方法和静态方法
public interface Print{
public static void aaa(){
System.out.println("aaa");
}
public default void bbb(){
System.out.println("bbb");
}
String print(String str,String str1);
}
4、方法引用
::
5、Stream(流水线)
- 集合遍历有弊端
- 筛选
- 切片
- 映射
- 查找
- 去重
- 统计
- 匹配
- 归约
特性
-
Stream只能操作一次
-
Stream方法返回的是新的流
-
Stream不调用终结方法,中间的操作不会执行
5.1、Stream的获取
public class Test {
public static void main(String[] args) {
//集合
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
Stream<String> stream = strings.stream();
//数组
String[] strings1={"zhangsan", "lisi", "wangwu", "zhaoliu"};
Stream<String> stream1 = Stream.of(strings1);
//map可以通过获取键集合,值集合,从而获得流
}
}
5.2、常用方法
方法声明 | 功能介绍 | 返回值 | 方法类型 |
---|---|---|---|
count | 统计个数 | long | 终结 |
forEach | 逐一处理 | void | 终结 |
filter | 过滤 | Stream | 函数拼接 |
limit | 取用前几个 | Stream | 函数拼接 |
skip | 跳过前几个 | Stream | 函数拼接 |
map | 映射 | Stream | 函数拼接 |
concat | 组合 | Stream | 函数拼接 |
5.3、forEach
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
strings.stream()
.forEach(System.out::println);
}
}
5.4、count
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
System.out.println(strings.stream()
.count());
}
}
5.5、filter
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
strings.stream()
.filter(s -> s.startsWith("z"))
.forEach(System.out::println);
}
}
5.6、limit
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
strings.stream()
.limit(1)
.forEach(System.out::println);
}
}
5.7、skip
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
strings.stream()
.skip(1)
.forEach(System.out::println);
}
}
5.8、map
完成数据转换、处理
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
strings.stream()
.map(s->s+="yoya")
.forEach(System.out::println);
}
}
5.9、sorted
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu");
strings.stream()
.sorted()
.forEach(System.out::println);
}
}
5.10、distinct
Stream流中的distinct方法对于基本数据类型是可以直接出重的,但是对于自定义类型,需要重写hashCode和equals方法来移除重复元素
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu","zhangsan");
strings.stream()
.distinct()
.forEach(System.out::println);
}
}
5.11、match
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu","zhangsan");
System.out.println(strings.stream()
.anyMatch(s -> s.startsWith("z")));
}
}
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu","zhangsan");
System.out.println(strings.stream()
.allMatch(s -> s.startsWith("z")));
}
}
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu","zhangsan");
System.out.println(strings.stream()
.noneMatch(s -> s.startsWith("z")));
}
}
5.12、find
findfirst返回第一个元素
findany返回随机一个元素
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu","zhangsan");
Optional<String> z = strings.stream()
.filter(s -> s.startsWith("z"))
.findAny();
System.out.println(z.get());
}
}
5.13、max,min
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu","zhangsan");
Optional<String> max = strings.stream()
.max((s1, s2) -> {
return s1.compareTo(s2);
});
System.out.println(max.get());
}
}
public class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("zhangsan", "lisi", "wangwu", "zhaoliu","zhangsan");
Optional<String> max = strings.stream()
.min((s1, s2) -> {
return s1.compareTo(s2);
});
System.out.println(max.get());
}
}
5.14、reduce
归约
public class Test {
public static void main(String[] args) {
Integer reduce = Stream.of(1, 2, 3, 4, 5)
.reduce(0, (a, b) -> {
return a + b;
});
System.out.println(reduce);
}
}
5.15、mapToInt
转为int
public class Test {
public static void main(String[] args) {
Integer[] integers={1, 2, 3, 4, 5};
Stream.of(integers)
.mapToInt(Integer::intValue)
.forEach(System.out::println);
}
}
5.16、concat
合并流
public class Test {
public static void main(String[] args) {
Integer[] integers={1, 2, 3, 4, 5};
Integer[] integers1={6,7,8,9,10};
Stream<Integer> concat = Stream.concat(Stream.of(integers), Stream.of(integers1));
concat
.mapToInt(Integer::intValue)
.forEach(System.out::println);
}
}
5.17、结果收集
public class Test {
public static void main(String[] args) {
Integer[] integers={1, 2, 3, 4, 5};
Integer[] integers1={6,7,8,9,10};
Stream<Integer> concat = Stream.concat(Stream.of(integers), Stream.of(integers1));
List<Integer> collect = concat
.collect(Collectors.toList());
System.out.println(collect);
}
}
public class Test {
public static void main(String[] args) {
Integer[] integers={1, 2, 3, 4, 5};
Integer[] integers1={6,7,8,9,10};
Stream<Integer> concat = Stream.concat(Stream.of(integers), Stream.of(integers1));
List<Integer> collect = concat
.collect(Collectors.toCollection(ArrayList::new));
System.out.println(collect);
}
}
public class Test {
public static void main(String[] args) {
Integer[] integers={1, 2, 3, 4, 5};
Integer[] integers1={6,7,8,9,10};
Stream<Integer> concat = Stream.concat(Stream.of(integers), Stream.of(integers1));
Integer[] integers2 = concat
.toArray(Integer[]::new);
System.out.println(Arrays.toString(integers2));
}
}
5.19、聚合
public class Test {
public static void main(String[] args) {
Person person0 = new Person(1, "zhangsan", true);
Person person1 = new Person(2, "lisi", true);
Person person2 = new Person(3, "wangwu", false);
Person person3 = new Person(4, "zhaoliu", true);
Person person4 = new Person(5, "qianqi", true);
Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
Optional<Person> collect = person
.collect(Collectors.maxBy((p1, p2) -> {
return p1.getId() - p2.getId();
}));
System.out.println(collect.get());
}
}
public class Test {
public static void main(String[] args) {
Person person0 = new Person(1, "zhangsan", true);
Person person1 = new Person(2, "lisi", true);
Person person2 = new Person(3, "wangwu", false);
Person person3 = new Person(4, "zhaoliu", true);
Person person4 = new Person(5, "qianqi", true);
Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
Integer collect = person
.collect(Collectors.summingInt(p -> p.getId()));
System.out.println(collect);
}
}
public class Test {
public static void main(String[] args) {
Person person0 = new Person(1, "zhangsan", true);
Person person1 = new Person(2, "lisi", true);
Person person2 = new Person(3, "wangwu", false);
Person person3 = new Person(4, "zhaoliu", true);
Person person4 = new Person(5, "qianqi", true);
Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
Double collect = person
.collect(Collectors.averagingInt(Person::getId));
System.out.println(collect);
}
}
public class Test {
public static void main(String[] args) {
Person person0 = new Person(1, "zhangsan", true);
Person person1 = new Person(2, "lisi", true);
Person person2 = new Person(3, "wangwu", false);
Person person3 = new Person(4, "zhaoliu", true);
Person person4 = new Person(5, "qianqi", true);
Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
Long collect = person
.collect(Collectors.counting());
System.out.println(collect);
}
}
5.20、分组
public class Test {
public static void main(String[] args) {
Person person0 = new Person(1, "zhangsan", true);
Person person1 = new Person(2, "lisi", true);
Person person2 = new Person(3, "zhangsan", false);
Person person3 = new Person(4, "lisi", true);
Person person4 = new Person(5, "zhangsan", true);
// Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
// Map<String, List<Person>> collect = person
// .collect(Collectors.groupingBy(person5 -> person5.getName()));
// System.out.println(collect);
// Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
// Map<String, List<Person>> collect = person
// .collect(Collectors.groupingBy(person5 -> person5.isGender()?"男":"女"));
// System.out.println(collect);
Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
Map<String, Map<String, List<Person>>> collect = person
.collect(Collectors.groupingBy(person5 -> person5.getName(), Collectors.groupingBy(person5 -> person5.isGender() ? "男" : "女")));
System.out.println(collect);
}
}
5.21、分区
public class Test {
public static void main(String[] args) {
Person person0 = new Person(1, "zhangsan", true);
Person person1 = new Person(2, "lisi", true);
Person person2 = new Person(3, "zhangsan", false);
Person person3 = new Person(4, "lisi", true);
Person person4 = new Person(5, "zhangsan", true);
Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
Map<Boolean, List<Person>> collect = person
.collect(Collectors.partitioningBy(person5 -> person5.isGender()));
System.out.println(collect);
}
}
5.22、joining
public class Test {
public static void main(String[] args) {
Person person0 = new Person(1, "zhangsan", true);
Person person1 = new Person(2, "lisi", true);
Person person2 = new Person(3, "zhangsan", false);
Person person3 = new Person(4, "lisi", true);
Person person4 = new Person(5, "zhangsan", true);
// Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
// String collect = person
// .map(person5 -> person5.getName())
// .collect(Collectors.joining());
// System.out.println(collect);
//
// Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
// String collect = person
// .map(person5 -> person5.getName())
// .collect(Collectors.joining("_"));
// System.out.println(collect);
Stream<Person> person = Stream.of(person0, person1, person2, person3, person4);
String collect = person
.map(person5 -> person5.getName())
.collect(Collectors.joining("_","###","$$$"));
System.out.println(collect);
}
}
5.23、并行流
public class Test {
public static void main(String[] args) {
Person person0 = new Person(1, "zhangsan", true);
Person person1 = new Person(2, "lisi", true);
Person person2 = new Person(3, "zhangsan", false);
Person person3 = new Person(4, "lisi", true);
Person person4 = new Person(5, "zhangsan", true);
Stream<Person> person01 = Stream.of(person0, person1, person2, person3, person4).parallel();
person01.map(s->{
System.out.println(Thread.currentThread()+"==="+s);
return s;
}).forEach(System.out::println);
}
}
并行流出现问题可尝试使用同步代码块
6、日期
- 设计不合理,在java.util和java.sql的包中都有日期类,java.util.Date同时包含日期和时间的,而 java.sql.Date仅仅包含日期,此外用于格式化和解析的类在java.text包下
- 非线程安全,java.util.Date是非线程安全的,所有的日期类都是可变的,这是java日期类最大的问 题之一
- 时区处理麻烦,日期类并不提供国际化,没有时区支持
JDK 8中增加了一套全新的日期时间API,这套API设计合理,是线程安全(每次都返回新对象)的,新的日期及时间API位于java.time包
- LocalDate :表示日期,包含年月日,格式为 2019-10-16
- LocalTime :表示时间,包含时分秒,格式为 16:38:54.158549300
- LocalDateTime :表示日期时间,包含年月日,时分秒,格式为 2018-09-06T15:33:56.750
- DateTimeFormatter :日期时间格式化类
- Instant:时间戳,表示一个特定的时间瞬间
- Duration:用于计算2个时间(LocalTime,时分秒)的距离
- Period:用于计算2个日期(LocalDate,年月日)的距离
- ZonedDateTime :包含时区的时间
6.1、LocalDate
public class Test {
public static void main(String[] args) {
//指定日期创建
LocalDate localDate=LocalDate.of(2020,10,19);
System.out.println(localDate);
//当前日期创建
System.out.println(LocalDate.now());
//更改日期
LocalDate localDate1 = localDate.withMonth(11);
System.out.println(localDate1);
//日期增减(plus,minus)
LocalDate localDate2 = localDate1.plusDays(1);
System.out.println(localDate2);
//日期比较
System.out.println(localDate.isAfter(localDate1));
System.out.println(localDate.isBefore(localDate1));
}
}
6.2、LocalTime
public class Test {
public static void main(String[] args) {
//指定时间创建
LocalTime localTime=LocalTime.of(10,19,0,123);
System.out.println(localTime);
//当前时间创建
System.out.println(LocalTime.now());
//时间更改
LocalTime localTime1 = localTime.withHour(11);
System.out.println(localTime1);
//时间增减(plus,minus)
LocalTime localTime2 = localTime1.plusHours(1);
System.out.println(localTime2);
//时间比较同上
}
}
6.3、LocalDateTime
public class Test {
public static void main(String[] args) {
LocalDate now = LocalDate.now();
LocalTime now1 = LocalTime.now();
LocalDateTime now2 = LocalDateTime.now();
System.out.println(LocalDateTime.of(now,now1));
System.out.println(now2);
//同样有设置、增减、比较
}
}
6.4、DateTimeFormatter
日期时间格式化与解析
public class Test {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dateTimeFormatter.format(now));
String str="2021-07-16 11:03:00";
LocalDateTime parse = LocalDateTime.parse(str, dateTimeFormatter);
System.out.println(parse);
}
}
6.5、Instant
public class Test {
public static void main(String[] args) {
Instant instant=Instant.now();
System.out.println(instant.getNano());
}
}
6.6、Duration、Period
Duration:时间差
Period:日期差
public class Test {
public static void main(String[] args) {
Duration duration = Duration.between(LocalTime.now(), LocalTime.of(12, 0, 0, 0));
System.out.println(duration.toHours());
System.out.println(duration.toMinutes());
System.out.println(duration.toMillis());
}
}
public class Test {
public static void main(String[] args) {
Period period = Period.between(LocalDate.now(), LocalDate.of(2022, 5, 2));
System.out.println(period.getDays());
System.out.println(period.getMonths());
System.out.println(period.getYears());
}
}
6.7、时区
public class Test {
public static void main(String[] args) {
//所有时区
for (String availableZoneId : ZoneId.getAvailableZoneIds()) {
System.out.println(availableZoneId);
}
//获取标准时间
ZonedDateTime zonedDateTime=ZonedDateTime.now(Clock.systemUTC());
System.out.println(zonedDateTime);
//获取默认时区时间
ZonedDateTime zonedDateTime1=ZonedDateTime.now();
System.out.println(zonedDateTime1);
//获取指定时区世家
ZonedDateTime zonedDateTime2=ZonedDateTime.now(ZoneId.of("America/Cuiaba"));
System.out.println(zonedDateTime2);
}
}
7、@Repeatable
允许重复注解
8、@Target属性
ElementType.TYPE_PARAMETER:允许注解写在声明语句中
ElementType.TYPE_USE:任何定义的地方都可以用