学习笔记输出来源:拉勾教育Java就业急训营
修改时间:2021年1月12日
作者:pp_x
邮箱:[email protected]
文章目录
- Java8新特性
-
- Java8概述
- 函数式接口
- lambda表达式
- 方法引用
- Stream接口
-
- 基本概念
- 使用步骤
- 创建方式
- 中间操作
- 映射
- 排序
- 终止操作
- optional类
-
- Java9新特性
-
- Java9的概述
- 模块化的使用
-
- 钻石操作符的使用升级
- 集合工厂方法
-
- InputStream的增强
- Java10新特性
-
- Java11新特性
-
- Java11概述
- 简化的编译操作
- String新增的方法
Java8新特性
Java8概述
- Java8是 Java 语言的一个重要版本,该版本于2014年3月发布,是自Java5以来最具革命性的版本,这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。
函数式接口
- 函数式接口主要指只包含一个抽象方法的接口,如:
java.lang.Runnable
、java.util.Comparator
接口等。
- Java8提供
@FunctionalInterface注解
来定义函数式接口,若定义的接口不符合函数式的规范便会报错。
接口名称 |
方法声明 |
功能介绍 |
Consumer |
void accept(T t) |
根据指定的参数执行操作 |
Supplier |
T get() |
得到一个返回值 |
Function |
R apply(T t) |
根据指定的参数执行操作并返回 |
Predicate |
boolean test(T t) |
判断指定的参数是否满足条件 |
lambda表达式
- Lambda 表达式是实例化函数式接口的重要方式,使用 Lambda 表达式可以使代码变的更加简洁紧凑。
- lambda表达式:参数列表、箭头符号->和方法体组成,而方法体中可以是表达式,也可以是语句块。
- 语法格式:
(参数列表) -> { 方法体; }
- 其中()、参数类型、{} 以及return关键字 可以省略。
方法引用
-
方法引用主要指通过方法的名字来指向一个方法而不需要为方法引用提供方法体,该方法的调用交给函数式接口执行。
-
方法引用使用一对冒号 :: 将类或对象与方法名进行连接,通常使用方式如下:
- 对象的非静态方法引用
ObjectName :: MethodName
- 类的静态方法引用
ClassName :: StaticMethodName
- 类的非静态方法引用
ClassName :: MethodName
- 构造器的引用
ClassName :: new
- 数组的引用
TypeName[] :: new
-
方法引用是在特定场景下lambda表达式的一种简化表示,可以进一步简化代码的编写使代码更加紧凑简洁,从而减少冗余代码。
函数式接口
package com.lagou.newproperties;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class FunctionalInterfaceTest {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("我是既没有参数又没有返回值的方法!");
}
};
runnable.run();
Runnable runnable1 = () -> System.out.println("我是既没有参数又没有返回值的方法!");
runnable1.run();
System.out.println("----------------------------------------------------------------------");
Consumer consumer = new Consumer() {
@Override
public void accept(Object o) {
System.out.println(o + "有参但没有返回值的方法就是我!");
}
};
consumer.accept("友情提示:");
Consumer consumer1 = o -> System.out.println(o + "有参但没有返回值的方法就是我!");
consumer1.accept("友情提示:");
System.out.println("----------------------------------------------------------------------");
Supplier supplier = new Supplier() {
@Override
public Object get() {
return "无参有返回值!";
}
};
System.out.println(supplier.get());
Supplier supplier1 = () -> "无参有返回值!";
System.out.println(supplier1.get());
System.out.println("----------------------------------------------------------------------");
Function function = new Function() {
@Override
public Object apply(Object o) {
return o;
}
};
System.out.println(function.apply("有参有返回值的方法"));
Function function1 = o -> o;
System.out.println(function1.apply("有参有返回值的方法"));
System.out.println("----------------------------------------------------------------------");
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
};
System.out.println(comparator.compare(10, 20));
Comparator comparator1 = (o1, o2) -> 0;
System.out.println(comparator1.compare(10, 20));
System.out.println("----------------------------------------------------------------------");
Predicate predicate = new Predicate() {
@Override
public boolean test(Object o) {
return false;
}
};
System.out.println(predicate.test("hello"));
Predicate predicate1 = o -> false;
System.out.println(predicate1.test("hello"));
}
}
方法引用
package com.lagou.newproperties;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class MethodReferenceTest {
public static void main(String[] args) {
Person person = new Person("zhangfei", 30);
Runnable runnable = new Runnable() {
@Override
public void run() {
person.show();
}
};
runnable.run();
System.out.println("-------------------------------------------------------------");
Runnable runnable1 = () -> person.show();
runnable1.run();
System.out.println("-------------------------------------------------------------");
Runnable runnable2 = person::show;
runnable2.run();
System.out.println("-------------------------------------------------------------");
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
person.setName(s);
}
};
consumer.accept("guanyu");
System.out.println("person = " + person);
System.out.println("-------------------------------------------------------------");
Consumer<String> consumer1 = s -> person.setName(s);
consumer1.accept("liubei");
System.out.println("person = " + person);
System.out.println("-------------------------------------------------------------");
Consumer<String> consumer2 = person::setName;
consumer2.accept("zhangfei");
System.out.println("person = " + person);
System.out.println("-------------------------------------------------------------");
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return person.getName();
}
};
System.out.println(supplier.get());
Supplier<String> supplier1 = () -> person.getName();
System.out.println(supplier1.get());
Supplier<String> supplier2 = person::getName;
System.out.println(supplier2.get());
System.out.println("-------------------------------------------------------------");
Function<String, Integer> function = new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s);
}
};
System.out.println(function.apply("12345"));
Function<String, Integer> function1 = s -> Integer.parseInt(s);
System.out.println(function1.apply("12345"));
Function<String, Integer> function2 = Integer::parseInt;
System.out.println(function2.apply("12345"));
System.out.println("-------------------------------------------------------------");
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
System.out.println(comparator.compare(10, 20));
Comparator<Integer> comparator1 = (o1, o2) -> Integer.compare(o1, o2);
System.out.println(comparator1.compare(10, 20));
Comparator<Integer> comparator2 = Integer::compare;
System.out.println(comparator2.compare(10, 20));
System.out.println("-------------------------------------------------------------");
Comparator<Integer> comparator3 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
};
System.out.println(comparator3.compare(10, 20));
Comparator<Integer> comparator4 = (o1, o2) -> o1.compareTo(o2);
System.out.println(comparator4.compare(10, 20));
Comparator<Integer> comparator5 = Integer::compareTo;
System.out.println(comparator5.compare(10, 20));
System.out.println("-------------------------------------------------------------");
Supplier<Person> supplier3 = new Supplier<Person>() {
@Override
public Person get() {
return new Person();
}
};
System.out.println(supplier3.get());
Supplier<Person> supplier4 = () -> new Person();
System.out.println(supplier4.get());
Supplier<Person> supplier5 = Person::new;
System.out.println(supplier5.get());
System.out.println("-------------------------------------------------------------");
BiFunction<String, Integer, Person> biFunction = new BiFunction<String, Integer, Person>() {
@Override
public Person apply(String s, Integer integer) {
return new Person(s, integer);
}
};
System.out.println(biFunction.apply("zhangfei", 30));
BiFunction<String, Integer, Person> biFunction1 = (s, integer) -> new Person(s, integer);
System.out.println(biFunction1.apply("zhangfei", 30));
BiFunction<String, Integer, Person> biFunction2 = Person::new;
System.out.println(biFunction2.apply("zhangfei", 30));
System.out.println("-------------------------------------------------------------");
Function<Integer, Person[]> function3 = new Function<Integer, Person[]>() {
@Override
public Person[] apply(Integer integer) {
return new Person[integer];
}
};
Person[] pArr = function3.apply(3);
System.out.println(Arrays.toString(pArr));
Function<Integer, Person[]> function4 = integer -> new Person[integer];
System.out.println(Arrays.toString(function4.apply(4)));
Function<Integer, Person[]> function5 = Person[]::new;
System.out.println(Arrays.toString(function5.apply(5)));
}
}
Stream接口
基本概念
java.util.stream.Stream
接口是对集合功能的增强,可以对集合元素进行复杂的查找、过滤、筛选等操作。
- Stream接口借助于Lambda 表达式极大的提高编程效率和程序可读性,同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势。
使用步骤
- 创建Stream,通过一个数据源获取一个流
- 转换Stream,每次返回获得一个新的Stream对象
- 对Stream进行聚合操作并产生结果
创建方式
- 方式一:通过调用集合的默认方法来获取流,如:
default Stream stream()
- 方式二:通过数组工具类中的静态方法来获取流,如:
static IntStream stream(int[] array)
- 方式三:通过Stream接口的静态方法来获取流,如:
static Stream of(T... values)
- 方式四:通过Stream接口的静态方法来获取流,
static Stream generate(Supplier extends T> s)
中间操作
方法声明 |
功能介绍 |
Stream filter(Predicate super T> predicate) |
返回一个包含匹配元素的流 |
Stream distinct() |
返回不包含重复元素的流 |
Stream limit(long maxSize) |
返回不超过给定元素数量的流 |
Stream skip(long n) |
返回丢弃前n个元素后的流 |
list.stream().filter(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return person.getAge() >= 18;
}
}).forEach(new Consumer<Person>() {
@Override
public void accept(Person person) {
System.out.println(person);
}
});
System.out.println("-------------------------------------------------------");
list.stream().filter(person -> person.getAge() >= 18).forEach(System.out::println);
list.stream().skip(2).limit(3).forEach(System.out::println);
映射
方法声明 |
功能 |
Stream map(Function super T,? extends R> mapper) |
返回每个处理过元素组成的流 |
Stream flatMap(Function super T,? extends Stream extends R>> mapper) |
返回每个被替换过元素组成的流,并将所有流合成一个流 |
list.stream().map(new Function<Person, Integer>() {
@Override
public Integer apply(Person person) {
return person.getAge();
}
}).forEach(System.out::println);
list.stream().map(Person::getAge).forEach(System.out::println);
排序
方法声明 |
功能 |
Stream sorted() |
返回经过自然排序后元素组成的流 |
Stream sorted(Comparator super T> comparator) |
返回经过比较器排序后元素组成的流 |
list.stream().sorted().forEach(System.out::println);
终止操作
方法声明 |
功能介绍 |
Optional findFirst() |
返回该流的第一个元素 |
boolean allMatch(Predicate super T> predicate) |
返回所有元素是否匹配 |
boolean noneMatch(Predicate super T> predicate) |
返回没有元素是否匹配 |
Optional max(Comparator super T> comparator) |
根据比较器返回最大元素 |
Optional min(Comparator super T> comparator) |
根据比较器返回最小元素 |
long count() |
返回元素的个数 |
void forEach(Consumer super T> action) |
对流中每个元素执行操作 |
System.out.println("------------------------判断集合中是否没有元素的年龄是大于45岁的-------------------------------");
boolean b1 = list.stream().noneMatch(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return person.getAge() > 45;
}
});
System.out.println(b1);
boolean b2 = list.stream().noneMatch(person -> person.getAge() > 45);
System.out.println(b2);
System.out.println("------------------------按照指定的比较器规则回去所有元素中的最大值-------------------------------");
Optional<Person> max = list.stream().max(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println(max);
max = list.stream().max(Person::compareTo);
System.out.println(max);
方法声明 |
功能 |
Optional reduce(BinaryOperator accumulator) |
返回结合后的元素值 |
System.out.println("------------------------实现将集合中所有元素的年龄映射出来-------------------------------");
Optional<Integer> reduce = list.stream().map(Person::getAge).reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer + integer2;
}
});
System.out.println("年龄的累加和是:"+reduce);
Optional<Integer> reduce1 = list.stream().map(Person::getAge).reduce(((integer, integer2) -> integer + integer2));
Optional<Integer> reduce2 = list.stream().map(Person::getAge).reduce(Integer::sum);
System.out.println("年龄的累加和是:"+reduce1);
System.out.println("年龄的累加和是:"+reduce2);
方法声明 |
功能介绍 |
R collect(Collector super T,A,R> collector) |
使用收集器对元素进行处理 |
list.stream().map(Person::getName).collect(Collectors.toList()).forEach(System.out::println);
optional类
基本概念
java.util.Optional
类可以理解为一个简单的容器,其值可能是null或者不是null,代表一个值存在或不存在。
- 该类的引入很好的解决空指针异常,不用显式进行空值检测
方法声明 |
功能介绍 |
static Optional ofNullable(T value) |
根据参数指定数值来得到Optional类型的对象 |
Optional map(Function super T,? extends U> mapper) |
根据参数指定规则的结果来得到Optional类型的对象 |
T orElse(T other) |
若该值存在就返回,否则返回other的数值。 |
public class OptionalTest {
public static void main(String[] args) {
String str1 = null;
if (null != str1) {
System.out.println("字符串的长度是:" + str1.length());
} else {
System.out.println("字符串为空,因此长度为0!");
}
Optional<String> optional = Optional.ofNullable(str1);
Optional<Integer> integer = optional.map(String::length);
System.out.println("integer = " + integer);
System.out.println(integer.orElse(0));
}
}
Java9新特性
Java9的概述
- Java9发布于2017年9月发布,带来了很多新特性,其中最主要的变化是模块化系统。
- 模块就是代码和数据的封装体,模块的代码被组织成多个包,每个包中包含Java类和接口,模块的数据则包括资源文件和其他静态信息。
模块化的使用
- 在 module-info.java 文件中,我们可以用新的关键词module来声明一个模块,具体如下:
module 模块名称 {}
模块化的优势
- 减少内存的开销。
- 可简化各种类库和大型应用的 开发和维护。
- 安全性,可维护性,提高性能。
钻石操作符的使用升级
- 在Java9中允许在匿名内部类的使用中使用钻石操作符。
集合工厂方法
基本概念
- Java9的List、Set和Map集合中增加了静态工厂方法of实现不可变实例的创建。
- 不可变体现在无法添加、修改和删除它们的元素。
- 不允许添加null元素对象。
public class CollectionTest {
public static void main(String[] args) {
List<Integer> list = List.of(1, 2, 3, 4, 5);
System.out.println(list);
Set<Integer> set = Set.of(6, 7, 8);
Map<Integer, String> map = Map.of(1, "one", 2, "two");
}
}
实际意义
- 保证线程安全:在并发程序中既保证线程安全性,也大大增强了并发时的效率。
- 被不可信的类库使用时会很安全。
- 如果一个对象不需要支持修改操作,将会节省空间和时间的开销。
- 可以当作一个常量来对待,并且这个对象在以后也不会被改变。
InputStream的增强
- InputStream类中提供了
transferTo
方法实现将数据直接传输到OutputStream中
package com.lagou.newproperties;
import java.io.*;
public class InputStreamTest {
public static void main(String[] args) {
InputStream inputStream = null;
OutputStream outputStream =null;
try {
inputStream = new FileInputStream("d:/a.txt");
outputStream = new FileOutputStream("d:/b.txt");
inputStream.transferTo(outputStream);
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null!= outputStream){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null!=inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Java10新特性
Java10概述
- Java10于2018年3月发布,改进的关键点包括一个本地类型推断、一个垃圾回收的增强。
- Java10计划只是一个短期版本,因此公开更新将在六个月内结束,9月份发布的Java11将是Java的长期支持(LTS)版本,LTS版本的发布每三年发布一次。
局部变量的推断
基本概念
- Java10可以使用var作为局部变量类型推断标识符,此符号仅适用于局部变量,增强for循环的索引,以及传统for循环的本地变量。
- 它不能使用于方法形式参数,构造函数形式参数,方法返回类型,字段,catch形式参数或任何其他类型的变量声明。
实际意义
- 标识符var不是关键字,只是一个保留的类型名称。这意味着var用作变量,方法名或包名的代码不会受到影响,但var不能作为类或则接口的名字。
- 避免了信息冗余。
- 对齐了变量名。
- 更容易阅读。
public class VarTest {
public static void main(String[] args) {
var num = 10;
var list = new LinkedList<Integer>();
list.add(10);
for (var v : list) {
System.out.println(v);
}
for (var i = 0; i < 10; i++) {
}
}
}
Java11新特性
Java11概述
- Java11于2018年9月正式发布,这是 Java 大版本周期变化 后的第一个长期支持版本,非常值得关注。
简化的编译操作
- 在Java11中可以使用java命令一次性进行编译和运行操作。
- 执行源文件中的第一个类必须包含主方法。
- 不可以使用其它源文件中自定义的类
String新增的方法
方法声明 |
功能介绍 |
boolean isBlank() |
判断字符串是否为空或只包含空白代码点 |
Optional map(Function super T,? extends U> mapper) |
根据参数指定规则的结果来得到Optional类型的对象 |
T orElse(T other) |
若该值存在就返回,否则返回other的数值。 |