JAVA8新特性
一、Lambda表达式
1.概念:
Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。 使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。
2.格式举例:
3.六种使用方式
@Test
public void test1(){
Runnable run=new Runnable () {
@Override
public void run() {
System.out.println ("大器晚成i");
}
};
run.run ();
System.out.println ("*************");
Runnable run2= ()->{
System.out.println ("霸王花i");
};
run2.run ();
}
@Test
public void test2(){
Consumer<String> consumer=new Consumer<String> () {
@Override
public void accept(String s) {
System.out.println (s);
}
};
consumer.accept ("易烊千玺真帅气");
System.out.println ("*********************");
Consumer<String> consumer1=(String s)-> {
System.out.println (s);
};
consumer1.accept ("易烊千玺超级无敌巨无霸帅气");
}
@Test
public void test3(){
Consumer<String> consumer3=new Consumer<String> () {
@Override
public void accept(String s) {
System.out.println (s);
}
};
consumer3.accept ("易烊千玺真帅气啊啊啊");
System.out.println ("*********************");
Consumer<String> consumer4=( s)-> {
System.out.println (s);
};
consumer4.accept ("是呀,易烊千玺超级无敌巨无霸帅气");
}
@Test
public void test4(){
Consumer<String> consumer6=s-> {
System.out.println (s);
};
consumer6.accept ("我也觉得易烊千玺超级无敌巨无霸帅气");
}
@Test
public void test5(){
Comparator<Integer> comparator=new Comparator<Integer> () {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println (o1);
System.out.println (o2);
return o1.compareTo (o2);
}
};
int compare = comparator.compare (12,6);
System.out.println (compare);
System.out.println ("********************");
Comparator<Integer> comparator2=(o1,o2)-> {
System.out.println (o1);
System.out.println (o2);
return o1.compareTo (o2);
};
int compare2 = comparator2.compare (12,36);
System.out.println (compare2);
}
@Test
public void test(){
Comparator<Integer> comparator2=(o1,o2)-> {
return o1.compareTo (o2);
};
int compare2 = comparator2.compare (12,36);
System.out.println (compare2);
System.out.println ("*************");
Comparator<Integer> comparator=(o1,o2)-> o1.compareTo (o2);
int compare = comparator.compare (12,36);
System.out.println (compare);
}
4.本质:
作为函数式接口的实例
二、函数式(Functional)接口
1.概念及举例:
如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口
举例:
package Java8;
@FunctionalInterface
public interface MyInterface {
void method();
}
2. Java内置四大核心函数式接口
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|
Consumer消费型接口 | T | void | 对类型为T的对象应用操作,包含方法:void accept(T t) | Supplier供给型接口 | 无 | T | 返回类型为T的对象,包含方法:T get() | Function<T,R>函数型接口 | T | R | 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t) | Predicate断定型接口 | T | boolean | 确定类型为T的对象是否满足某约束,并返回boolean值。包含方法:boolean test(T t) |
3.消费型接口举例
@Test
public void test(){
happyTime (3, new Consumer<Double> () {
@Override
public void accept(Double aDouble) {
System.out.println ("我花费了"+aDouble+"元去买了一瓶快乐肥宅水");
}
});
System.out.println ("************************");
happyTime (6, money->System.out.println ("我花费了"+money+"元去买了双倍快乐"));
}
public void happyTime(double money, Consumer<Double> con){
con.accept (money);
}
4.断定型接口举例
@Test
public void test2(){
List<String> list = Arrays.asList ("北京", "天津", "东京", "京曲", "昆曲", "秦腔");
List<String> filterList= filterString (list, new Predicate<String> () {
@Override
public boolean test(String s) {
return s.contains ("京");
}
});
System.out.println (filterList);
System.out.println ("**********");
List<String> filterList2= filterString(list,s-> s.contains ("曲"));
System.out.println (filterList2);
}
public List<String> filterString(List<String>list, Predicate<String> pre ){
ArrayList<String> stringArrayList=new ArrayList<> ();
for (String s:list) {
if(pre.test (s)){
stringArrayList.add (s);
}
}
return stringArrayList;
}
三、方法引用与构造器引用
1.方法引用的使用
2.方法引用的使用的具体三种情况
情况一: 对象:∶非静态方法
@Test
public void test1(){
Consumer<String> consumer=s -> System.out.println (s);
consumer.accept ("易烊千玺");
System.out.println ("*************");
PrintStream ps=System.out;
Consumer<String> consumer2= ps::println;
consumer2.accept ("YiYangQianXi");
}
@Test
public void test2(){
Employee employee=new Employee("Tom",18);
Supplier<String> supplier=()->employee.getName ();
System.out.println (supplier.get ());
System.out.println ("***************");
Supplier<String> supplier1=employee::getName;
System.out.println (supplier1.get ());
}
情况二: 类::静态方法
@Test
public void test3(){
Comparator<Integer> comparator=(o1,o2)->Integer.compare (o1,o2);
System.out.println (comparator.compare (12, 36));
System.out.println ("******************");
Comparator<Integer> comparator2=Integer::compareTo;
System.out.println (comparator2.compare (12,6));
}
@Test
public void test4(){
Function<Double, Long> function=new Function<Double, Long> () {
@Override
public Long apply(Double aDouble) {
return Math.round (aDouble);
}
};
System.out.println (function.apply (12.3));
System.out.println ("***********");
Function<Double, Long> function2=aDouble -> Math.round (aDouble);
System.out.println (function2.apply (12.8));
System.out.println ("********************");
Function<Double, Long> function3=Math::round;
System.out.println (function3.apply (19.1));
}
情况三: 类::非静态方法
@Test
public void test5(){
Comparator<String> comparator=new Comparator<String> () {
@Override
public int compare(String o1, String o2) {
return o1.compareTo (o2);
}
};
System.out.println (comparator.compare ("abc", "ab"));
System.out.println ("***********");
Comparator<String> comparator2=(o1,o2)->o1.compareTo (o2);
System.out.println (comparator2.compare ("am", "abm"));
System.out.println ("***********");
Comparator<String> comparator3=String::compareTo;
System.out.println (comparator3.compare ("a", "f"));
}
@Test
public void test6(){
BiPredicate<String,String> biPredicate=new BiPredicate<String, String> () {
@Override
public boolean test(String o, String o2) {
return o.equals (o2);
}
};
System.out.println (biPredicate.test ("ab", "ab"));
System.out.println ("****************");
BiPredicate<String,String> biPredicate2=(o,o2)-> o.equals (o2);
System.out.println (biPredicate2.test ("abc", "ab"));
System.out.println ("****************");
BiPredicate<String,String> biPredicate3=String::equals;
System.out.println (biPredicate3.test ("b", "ab"));
}
@Test
public void test7(){
Employee e1=new Employee ("Jerry",66);
Function<Employee,String> function=new Function<Employee, String> () {
@Override
public String apply(Employee employee) {
return employee.getName ();
}
};
System.out.println (function.apply (e1));
System.out.println ("*****************");
Function<Employee,String> function2=employee->e1.getName ();
System.out.println (function2.apply (e1));
System.out.println ("*****************");
Function<Employee,String> function3=Employee::getName;
System.out.println (function3.apply (e1));
}
3.构造器引用
和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。 抽象方深的返回值类型即为构造器所属的类的类型
@Test
public void test1(){
Supplier<Employee> supplier=new Supplier<Employee> () {
@Override
public Employee get() {
return new Employee ();
}
};
System.out.println (supplier.get ());
System.out.println ("**************");
Supplier<Employee> supplier2=()->new Employee ();
System.out.println (supplier2.get ());
System.out.println ("*****************");
Supplier<Employee> supplier3=Employee::new;
System.out.println (supplier3.get ());
}
@Test
public void test2(){
Function<Integer,Employee> function=age->new Employee(age);
Employee employee = function.apply (13);
System.out.println (employee);
System.out.println ("***************");
Function<Integer,Employee> function2=Employee::new;
Employee employee1 = function2.apply (19);
System.out.println (employee1);
}
@Test
public void test3(){
BiFunction<String,Integer,Employee> biFunction=(name,age ) -> new Employee (name,age);
Employee employee = biFunction.apply ( "霸王花",16);
System.out.println (employee);
System.out.println ("************");
BiFunction<String,Integer,Employee> biFunction2=Employee::new;
Employee employee2 = biFunction2.apply ( "易烊千玺",21);
System.out.println (employee2);
}
4.数组引用
大家可以把数组看做是一个特殊的类,则写法与构造器引用一致
@Test
public void test4(){
Function<Integer,String[]> function=len->new String[len];
String[] apply = function.apply (5);
System.out.println (Arrays.toString (apply));
System.out.println ("****************");
Function<Integer,String[]> function2=String[]::new;
String[] apply2 = function2.apply (3);
System.out.println (Arrays.toString (apply2));
}
四、 Stream API
1. Stream API 的概述
2.创建Stream的实例化
①通过集合
@Test
public void test(){
List<Employee> employeeList = EmployeeData.getEmployees ();
Stream<Employee> employeeStream = employeeList.stream ();
Stream<Employee> parallelStream = employeeList.parallelStream ();
}
②通过数组
@Test
public void test2(){
int arr[]=new int[]{1,2,44,21,12};
IntStream intStream = Arrays.stream (arr);
Employee e1=new Employee ("Tom",18);
Employee e2=new Employee ("Linda",12);
Employee ep[]=new Employee[]{e1,e2};
Stream<Employee> employeeStream = Arrays.stream (ep);
}
③通过Stream的of()
@Test
public void test3(){
Stream<Integer> integerStream = Stream.of (1, 32, 12, 33, 13);
}
④创建无限流
@Test
public void test4(){
Stream.iterate (0,t->t+2).limit (10).forEach (System.out::println);
System.out.println ("*********************");
Stream.generate (Math::random).limit (5).forEach (System.out::println);
}
3. Stream的中间操作
①筛选与切片
方法名 | 含义 |
---|
filter(Predicate p) | 接收Lambda ,从流中排除某些元素 | limit(n) | 截断流,使其元素不超过给定数量 | skip(n) | 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n 个,则返回 | distinct() | 筛选,通过流所生成元素的 hashCode()和equals()去除重复元素 |
@Test
public void test1(){
List<Employee> employeeList = EmployeeData.getEmployees ();
Stream<Employee> stream = employeeList.stream ();
stream.filter (e -> e.getAge () > 25).forEach (System.out::println);
System.out.println ("**************");
employeeList.stream ().limit (1).forEach (System.out::println);
System.out.println ("**************");
employeeList.stream ().skip (2).forEach (System.out::println);
System.out.println ("*******************");
employeeList.add (new Employee ("AAA",16));
employeeList.add (new Employee ("AAA",18));
employeeList.add (new Employee ("AAA",18));
employeeList.add (new Employee ("AAA",18));
employeeList.stream ().distinct ().forEach (System.out::println);
}
②映射
方法 | 含义 |
---|
map(Function f) | 接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数会将元素转换成其他形式或提取信息,该函数会被应用到每个元素上,并将其映射成一个新的元素。 | flatNap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 |
@Test
public void test(){
List<String> arrayList= Arrays.asList ("aa","bb","cc");
arrayList.stream ().map (s -> s.toUpperCase ()).forEach (System.out::println);
System.out.println ("*****************");
List<Employee> employees = EmployeeData.getEmployees ();
Stream<String> stringStream = employees.stream ().map (e -> e.getName ());
stringStream.filter (name->name.length ()>2).forEach (System.out::println);
System.out.println ("*****************");
}
③排序
方法 | 含义 |
---|
sorted() | 产生一个新流,其中按自然顺序排序 | sorted(Comparator com) | 产生一个新流,其中按比较器顺序排序 |
@Test
public void test3(){
List<Integer> list=Arrays.asList (1,23,12,56,32);
list.stream ().sorted ().forEach (System.out::println);
System.out.println ("*********************");
List<Employee> employees = EmployeeData.getEmployees ();
employees.stream ().sorted ((e1,e2)->Integer.compare (e1.getAge (),e2.getAge ())).forEach (System.out::println);
}
4.测试Stream的终止操作
①匹配与查找
方法 | 含义 |
---|
allMatch(Predicate p) | 检查是否匹配所有元素 | anyMatch(Predicate p) | 检查是否至少匹配一个元素 | noneMatch(Predicate p) | 检查是否没有匹配的元素 | findFirst | 返回第一个元素 | findAny | 返回当前流中的任意元素 | count | 返回流中元素的总个数 | max ( Comparator c) | 返回流中最大值 | min(comparator c) | 返回流中最小值 | forEach(Consumer c | 内部迭代 |
@Test
public void test(){
List<Employee> employees = EmployeeData.getEmployees ();
boolean b = employees.stream ().allMatch (e -> e.getAge () > 18);
System.out.println (b);
boolean b1 = employees.stream ().anyMatch (e -> e.getAge () > 30);
System.out.println (b1);
boolean b2 = employees.stream ().noneMatch (e -> e.getName ().contains ("张三"));
System.out.println (b2);
}
@Test
public void test2(){
List<Employee> employees = EmployeeData.getEmployees ();
Optional<Employee> first = employees.stream ().findFirst ();
System.out.println (first);
Optional<Employee> any = employees.stream ().findAny ();
System.out.println (any);
long count = employees.stream ().count ();
System.out.println (count);
Stream<Integer> integerStream = employees.stream ().map (e -> e.getAge ());
Optional<Integer> max = integerStream.max (Double::compare);
System.out.println (max);
Optional<Employee> min = employees.stream ().min ((e1, e2) -> Double.compare (e1.getAge (), e2.getAge ()));
System.out.println (min);
}
②规约
方法 | 含义 |
---|
reduce(T identity, BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回T | reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回Optional |
@Test
public void test3(){
List<Integer> list= Arrays.asList (12,9,33,23);
Integer sum = list.stream ().reduce (0, Integer::sum);
System.out.println (sum);
List<Employee> employees = EmployeeData.getEmployees ();
Stream<Integer> integerStream = employees.stream ().map (e -> e.getAge ());
Optional<Integer> agesum = integerStream.reduce (Integer::sum);
System.out.println (agesum);
}
③收集
方法 | 含义 |
---|
collect(Collector c) | 将流转换为其他形式。接收一个 |
@Test
public void test5(){
List<Employee> employees = EmployeeData.getEmployees ();
List<Employee> list = employees.stream ().filter (e->e.getAge ()>25).collect (Collectors.toList ());
System.out.println (list);
Set<Employee> set = employees.stream ().filter (e -> e.getAge () > 18).collect (Collectors.toSet ());
System.out.println (set);
}
五、 Optional 类
1.概念:
Optional类(java.util.Optional)是一个容器类、它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。 原来用null表示一个值不存在,现在 Optional可以更好的表达这个概念。并且可以避免空指针异常。
Optional类:为了在程序中避免出现空指针异常而创建的。
2.常用方法及举例
①创建Optional类对象的方法
Optional.of(T t) | 创建一个Optional实例,t必须非空 |
---|
Optional.empty( ) | 创建一个空的Optional实例 | Optional.ofNullable(T t) | t可以为null |
@Test
public void test1(){
Girl girl=new Girl ();
Optional<Girl> girlOptional = Optional.of (girl);
}
@Test
public void test2(){
Girl girl=new Girl ();
girl=null;
Optional<Girl> girlOptional = Optional.ofNullable (girl);
System.out.println (girlOptional);
}
②判断Optional容器中是否包含对象
boolean isPresent | 判断是否包含对象 |
---|
void ifPresent(Consum<? super T> consumer) | 接口的实现代码,并且该值会作为参数传给它 |
③获取Optional容器的对象
T get() | 如果调用对象包含值,返回该值,否则抛异常 |
---|
T orElse(T other) | 如果有值则将其返回,否则返回指定的other对象 | T orElseGet(Supplier<? extends T> other) | 如果有值则将其返回,否则返回指定的Supplier接口实现提供的对象 | T orElseThrow(Supplier<? extends T> exceptionSupplier) | 如果有值则将其返回,否则返回,否则抛出Supplier接口实现提供的异常 |
优化前:使用if防止其为空
@Test
public void test2(){
Girl girl=new Girl ();
girl=null;
Optional<Girl> girlOptional = Optional.ofNullable (girl);
System.out.println (girlOptional);
Girl girl1 = girlOptional.orElse (new Girl ("霸王花"));
System.out.println (girl1);
}
public String getGirlName(Boy boy){
return boy.getGirl ().getName ();
}
@Test
public void test3(){
Boy boy=new Boy ();
String name = getGirlName (boy);
System.out.println (name);
}
public String getGirlName1(Boy boy){
if(boy!=null){
Girl girl = boy.getGirl ();
if(girl!=null){
return girl.getName ();
}
}
return null;
}
优化后:使用Optional类
@Test
public void test4(){
Boy boy=new Boy ();
boy=null;
String name1 = getGirlName1 (boy);
System.out.println (name1);
}
public String getGirlName2(Boy boy){
Optional<Boy> optionalBoy = Optional.ofNullable (boy);
Boy boy1 = optionalBoy.orElse (new Boy (new Girl ("大器晚成")));
Girl girl = boy1.getGirl ();
Optional<Girl> optionalGirl = Optional.ofNullable (girl);
Girl girl1 = optionalGirl.orElse (new Girl ("霸王花"));
String name = girl1.getName ();
return name;
}
@Test
public void test5(){
Boy boy=null;
boy=new Boy ();
String girlName = getGirlName2 (boy);
System.out.println (girlName);
}
六、补充:
补充一:
Boy类
package Java8.day1;
public class Boy {
private Girl girl;
public Boy() {
}
public Boy(Girl girl) {
this.girl = girl;
}
public Girl getGirl() {
return girl;
}
public void setGirl(Girl girl) {
this.girl = girl;
}
@Override
public String toString() {
return "Boy{" + "girl=" + girl + '}';
}
}
Girl类
package Java8.day1;
import java.util.stream.Stream;
public class Girl {
private String name;
public Girl(String name) {
this.name = name;
}
public Girl() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Girl{" + "name='" + name + '\'' + '}';
}
}
补充二:
Employee类
package Java8;
public class Employee {
private String name;
private int age;
public Employee(int age) {
System.out.println ("Employee(Integer age)");
this.age=age;
}
public Employee() {
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Employee{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
EmployeeData类
package Java8.day2;
import java.util.ArrayList;
import java.util.List;
public class EmployeeData {
public static List<Employee> getEmployees(){
ArrayList<Employee> list=new ArrayList<> ();
list.add (new Employee ("张三",30));
list.add (new Employee ("李四",36));
list.add (new Employee ("王麻子",23));
return list;
}
}
|