jdk8新特性
1,lambda表达式
完整的Lambda表达式由三部分组成:参数列表、箭头、声明语句;
(Type1 param1, Type2 param2, ..., TypeN paramN) -> { statment1; statment2; //............. return statmentM;}
(1)绝大部分情况下不用声明参数类型。上下文可以识别
(param1,param2, ..., paramN) -> { statment1; statment2; //............. return statmentM;}
(2)当参数只有一个
param1 -> { statment1; statment2; //............. return statmentM;}
(3)当声明语句只有一句
param1 -> statment
###代码实例
1.1,使用() -> {} 代替匿名类
jdk7的写法
public class TestThread {
public static void main(String[] s) {
/**
* 不使用Lambda
*/
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("no use lambda");
}
});
lambda jdk8的写法
Thread t2 = new Thread(() -> System.out.println("use lambda"));
t1.run();
t2.run();
###lambda表达式就像一个抽象方法。没有方法体一样。
1.2,lambda表达式在集合中的基本应用
1.2.1,遍历集合
package com.testjdk8.test.thread;
import java.util.*;
public class Test {
public static void main(String[] args) {
List<String>list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
//1,jdk7,循环遍历list
for(String str:list){
System.out.println(str);
}
//2,jdk7,循环遍历list
Iterator<String> iterator= list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//jdk8,lambda表达式
list.forEach(
(s) -> System.out.println(s)
);
}
}
1.2.2,包含与筛选
1,jdk1.7判断集合是否包含这个元素
System.out.println(list.contains("a"));
2,lambda表达式筛选,用到stream流
Predicate<String>contain1=n -> n.contains("a");
Predicate<String>contain2=n -> n.contains("b");
list.stream().filter(contain1).forEach(n -> System.out.println(n));
3.lambda表达式判断集合是否包含这个元素
System.out.println(contain1.test("a"));
4,或者直接通过是否包含这个元素,并且遍历
list.stream().filter(n -> contain1.test(n)).forEach(s -> System.out.println(s));
5,是否同时包含,遍历
list.stream().filter(contain1.and(contain2)).forEach(s -> System.out.println(s));
6,是否其中一个包含。全部遍历
list.stream().filter(contain1.or(contain2)).forEach(s -> System.out.println(s));
5,6有点类似mysql的and和or
1.2.3,将一个集合合并到另一个集合
List<String>newlist=list.stream().filter(contain1.or(contain2)).collect(Collectors.toList());
System.out.println(newlist.isEmpty());
newlist.forEach(n -> System.out.println(n));
1.2.4,流水线处理
List<Integer> integers = Arrays.asList(4, 5, 6,1, 2, 3,7, 8,8,9,10);
//过滤出偶数列表 [4,6,8,8,10]
List<Integer> evens = integers.stream().filter(i -> i % 2 == 0).collect(Collectors.toList());
//转成平方列表
List<Integer> squareList = integers.stream().map(i -> i * i).collect(Collectors.toList());
//分别打印输出
evens.forEach(f -> System.out.println(f));
squareList.forEach(f -> System.out.println(f));
1.2.5,并行流处理
将之前1.2.4的代码拷贝
//转成平方列表,并行处理
List<Integer> squareList1 = integers.stream().parallel().map(i -> i * i).collect(Collectors.toList());
结果一样速度更快。线程不安全
1.2.6,外部迭代和内部迭代
1.7我们用的是外部迭代。就是foreach增强for循环
1.8以后用lambda表达式就是内部迭代
可以用内部迭代取代外部迭代
//外部迭代
List<String> features1 = Arrays.asList("Lambdas", "Default Method", "StreamAPI");
for (String feature : features1) {
System.out.println(feature);
}
//内部迭代
List<String> features2 = Arrays.asList("Lambdas", "Default Method", "StreamAPI");
features2.stream().forEach(n -> System.out.println(n));
2,stream流
这个流不同于io流
完全不同的两个概念
先看一段伪代码
List<Person> personList = fromDB(); // 获得List<Person>
int limit = 10; // 限制条件
List<String> nameList = new ArrayList(); // 收集的姓名集合
for(Person personItem : personList){
if(personItem.age == 70){ // 满足条件
nameList.add(personItem.name); // 加入姓名集合
if(nameList.size() >= 10){ // 判断是否超过限制
break;
}
}
}
return nameList;
这段是不是很熟悉?
各种判断条件和循环语句
如果换成下面呢?
List<Person> personList = fromDB(); // 获得List<Person>
List<String> nameList = personList.stream()
.filter(item->item.age == 70) // 过滤条件
.limit(10) // limit限制条件
.map(item->item.name) // 获得姓名
.collect(Collector.toList()); // 转化为list
return nameList;
这就是整一套的流操作
代码实例
package com.testjdk8.test.thread;
public class Person {
private int age;
private String name;
Person(){}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.testjdk8.test.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
//仿造数据库返回对象和list
public static void main(String[] args) {
//创建三个person对象
Person person=new Person(35,"xiaowang");
Person person2=new Person(20,"xiaofang");
Person person3=new Person(20,"jiansong");
//创建集合对象
List<Person>list=new ArrayList<>();
list.add(person);
list.add(person2);
list.add(person3);
//jdk1.7操作集合
List<String>nameList=new ArrayList<>();
for(Person person1:list){
if(person1.getAge()==20){
nameList.add(person1.getName());
}
if(nameList.size()>=1){
break;
}
}
for(String name:nameList){
System.out.println("在集合中的名字:"+name);
}
//jdk1.8 stream流操作
List<String>nameList2=list.stream()
.filter(item ->item.getAge()==20)
.limit(1)
.map(item -> item.getName())
.collect(Collectors.toList());
nameList2.forEach(f -> System.out.println("流式操作"+f));
}
}
####需求:需要一个j开头名字的namelist集合如何操作?打印
//进阶
List<String>nameList3=list.stream()
.filter(item -> item.getAge()>=20)
.filter(item -> item.getName().startsWith("j"))
.limit(1)
.map(item -> item.getName())
.collect(Collectors.toList());
nameList3.forEach(f -> System.out.println("过滤==="+f));
###stream流的特性是惰性操作。。包括中间操作和终止操作。因为所有的中间操作都是返回stream所以可以链式,流水线式的操作。而终止操作只能有一个。
流的中间操作
1.filter(Predicate) :将结果为false的元素过滤掉
2.map(fun) :转换元素的值,可以用方法引元或者lambda表达式
3.flatMap(fun) :若元素是流,将流摊平为正常元素,再进行元素转换
4.limit(n) :保留前n个元素
5.skip(n) :跳过前n个元素
6.distinct() :剔除重复元素
7.sorted() :将Comparable元素的流排序
8.sorted(Comparator) :将流元素按Comparator排序
9.peek(fun) :流不变,但会把每个元素传入fun执行,可以用作调试
流的终结操作
(1)约简操作
1.reduce(fun) :从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数
2.reduce(a, fun) :a为幺元值,作为累积器的起点
3.reduce(a, fun1, fun2) :与二元变形类似,并发操作中,当累积器的第一个参数与第二个参数都为流元素类型时,可以对各个中间结果也应用累积器进行合并,但是当累积器的第一个参数不是流元素类型而是类型T的时候,各个中间结果也为类型T,需要fun2来将各个中间结果进行合并
(2)收集操作
1.iterator():
2.forEach(fun):
3.forEachOrdered(fun) :可以应用在并行流上以保持元素顺序
4.toArray():
5.toArray(T[] :: new) :返回正确的元素类型
6.collect(Collector):
7.collect(fun1, fun2, fun3) :fun1转换流元素;fun2为累积器,将fun1的转换结果累积起来;fun3为组合器,将并行处理过程中累积器的各个结果组合起来
(3)查找与收集操作
1.max(Comparator):返回流中最大值
2.min(Comparator):返回流中最小值
3.count():返回流中元素个数
4.findFirst() :返回第一个元素
5.findAny() :返回任意元素
6.anyMatch(Predicate) :任意元素匹配时返回true
7.allMatch(Predicate) :所有元素匹配时返回true
8.noneMatch(Predicate) :没有元素匹配时返回true
2.1,并行流
简单的将list的元素取出来再添加到另一个集合中
package com.testjdk8.test.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
//仿造数据库返回对象和list
public static void main(String[] args) {
// 使用一个容器装载 100 个数字,通过 Stream 并行处理的方式将容器中为单数的数字转移到容器 parallelList
List<Integer> integerList= new ArrayList<Integer>();
for (int i = 0; i <100; i++) {
integerList.add(i);
}
List<Integer> parallelList = new ArrayList<Integer>() ;
parallelList=integerList.stream()
.parallel()
.filter(i->i%2==1)
.collect(Collectors.toList());
parallelList.forEach(i -> System.out.println(i));
}
}
2.2,串行流
之前没加.parallel()的就是串行流。。并行流转串行流的方法
List<Integer> parallelList = new ArrayList<Integer>() ;
parallelList=integerList.stream()
.parallel()
.sequential()
.filter(i->i%2==1)
.collect(Collectors.toList());
parallelList.forEach(i -> System.out.println(i));
3,函数式接口
jdk8常见的函数式接口
Supplier None T 提供者 工厂方法创建对象
Consumer T void 消费者 输出一个值
Predicate T boolean 谓语,顾名思义,中文中的‘是’与‘不是’是中文语法的谓语
Function T R 函数 获得某个对象的名字
BinaryOperator (T, T) T 二元操作符,二元(就是数学里二元一次方程那个二元,代表 2 个的意思),双重的。
即有两个操作数 例如求两个数的乘积(*)
UnaryOperator T T 一元操作符,只有一个操作数 逻辑非(!)
3.1,Supplier接口(生成数据)
3.1.1,直接创建Supplier字符串对象,调用get方法
package com.testjdk8.test.thread;
import java.util.function.Supplier;
public class Supplierdemo {
public static void main(String[] args) {
Supplier supplier=() -> "helloworld";
System.out.println(supplier.get());
}
}
3.1.2,Supplier创建对象
package com.testjdk8.test.thread;
import java.util.function.Supplier;
//主类
public class DemoSupplier {
//员工类
private static class Employee {//注意static
public String toString() {
return "我是员工";
}
}
public static void main(String[] args) {
//使用 Lambda 传入 Supplier 对象,将生成一个员工对象//此时仅仅是实例化了接口并未执行里面代码
Supplier supplier = ()->new Employee();
//输出员工对象
System.out.println(supplier.get());
}
}
3.1.3,Supplier作为方法参数
package com.testjdk8.test.thread;
import java.util.function.Supplier;
//主类
public class DemoSupplier {
public static void main(String[] args) {
int[] arr = {12, 68, 10, 2, 99, 313, 46};
// 调用 getMax 方法获得最大值,Lambda 相当于方法体
int num = getMax(() -> {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
});
//输出最大值
System.out.println("最大值是:" + num);
}
//使用 Supplier 做为参数
public static int getMax(Supplier<Integer> supplier) {
return supplier.get();
}
}
3.2,consumer接口(消费数据)
3.2.1,直接使用consumer对象
package com.testjdk8.test.thread;
import java.util.function.Consumer;
public class DemoSupplier {
public static void main(String[] args) {
Consumer consumer=t -> System.out.println(t);
consumer.accept("goodgoodstudy");
}
}
3.2.2,consumer作为参数1
package com.testjdk8.test.thread;
import java.util.Arrays;
import java.util.List;
public class DemoSupplier {
public static void main(String[] args) {
//将数组转成 List 对象
List names = Arrays.asList("孙悟空", "猪八戒", "白骨精", "嫦娥");
//打印每一个字符串,forEach 的参数就是 Consumer
names.forEach(t -> System.out.println(t));
}
}
3.2.3,consumer作为参数2
数组分割字符串
package com.testjdk8.test.thread;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class DemoSupplier {
public static void main(String[] args) {
String[] arr = {"张飞,男", "貂蝉,女", "曹操,男", "孙尚香,女"};//这里的 s 表示数组中的每个元素
printInfo(arr, s -> {
System.out.println("姓名:" + s.split(",")[0]);
}, s -> {
System.out.println("性别:" + s.split(",")[1]);
});
}
public static void printInfo(String[] arr, Consumer<String> name, Consumer<String> gender) {
for (String s : arr) {
name.andThen(gender).accept(s);
System.out.println("------------------");
}
}
}
3.3,Predicate接口(返回boolean)
3.3.1,test()方法
package com.testjdk8.test.thread;
import java.util.function.Predicate;
public class DemoSupplier {
public static void main(String[] args) {//创建一个 Predicate 谓语对象,boolean test(T t)方法接收字符串类型,返回 boolean 类型
Predicate<String> predicate = s -> s.length() > 5;
//两次调用 test方法看运行结
System.out.println("Hello 的长度是否大于 5:" + predicate.test("Hello"));
System.out.println("Predicate 的长度是否大于 5:" + predicate.test("Predicate"));
}
}
3.3.2,and()方法
package com.testjdk8.test.thread;
import java.util.function.Predicate;
public class DemoSupplier {
public static void main(String[] args){
//创建 2 个需要判断的字符串
String s1 = "Hello world";
String s2 = "Hello World";
// 使用 Lambda 表达式,创建两个 Predicate 对象
//判断 s 是否包含 H
Predicate<String> p1 = s -> s.contains("H");
//判断 s 是否包含 W
Predicate<String> p2 = s -> s.contains("W");
//调用 and 方法
System.out.println(s1 + "是否包含 H 和 W:" + p1.and(p2).test(s1));
System.out.println(s2 + "是否包含 H 和 W:" + p1.and(p2).test(s2));
}
}
3.3.3,or()方法
package com.testjdk8.test.thread;
import java.util.function.Predicate;
public class DemoSupplier {
public static void main(String[] args) {
//创建三个字符串
String s1 = "Hello World"; //大于 10
String s2 = "Java"; //小于 5
String s3 = "I am boy"; //既不大于 10,又不小于 5
//使用 Lambda 创建 2 个 Predicate 接口对象
Predicate<String> p1 = s -> s.length() > 10;
Predicate<String> p2 = s -> s.length() < 5;
//输出每个字符串的测试结果
System.out.println(s1 + "=" + p1.or(p2).test(s1));
System.out.println(s2 + "=" + p1.or(p2).test(s2));
System.out.println(s3 + "=" + p1.or(p2).test(s3));
}
}
3.3.4, 默认方法 negate() 取反
package com.testjdk8.test.thread;
import java.util.function.Predicate;
public class DemoSupplier {
public static void main(String[] args) {
int age1 = 25; //25 岁
int age2 = 15; //15 岁
Predicate<Integer> predicate = (a) -> a < 18; //判断是否小于 18 岁
System.out.println(age1 + "小于 18 岁,取反:" + predicate.negate().test(age1));
System.out.println(age2 + "小于 18 岁,取反:" + predicate.negate().test(age2));
}
}
3.3.5,比较两个对象是否相等 isEqual ()
package com.testjdk8.test.thread;
import java.util.function.Predicate;
public class DemoSupplier {
public static void main(String[] args) {
//通过静态方法直接返回 Predicate 对象
Predicate predicate = Predicate.isEqual("newboy");
//调用 test()方法传入另两个字符串分别比较
System.out.println("两个字符串是否相等:" + predicate.test("newboy"));
System.out.println("两个字符串是否相等:" + predicate.test("NewBoy"));
}
}
3.3.6,应用实例
需求说明集合当中有多条“姓名+性别”的信息如下:“张飞,男”, “貂蝉,女”, “曹操,男”,“孙尚香,女”,“小乔,女”
请通过 Predicate 接口的 and 组合方法,将符合要求的字符串筛选到集合 ArrayList 中,
需要同时满足两个条件:1) 必须为女生 2) 姓名为两个字
开发步骤:1) 创建第 1 个 Predicate 判断条件:使用逗号分隔的第 0 个元素姓名长度是 2
-
创建第 2 个 Predicate 判断条件:使用逗号分隔的第 1 个元素性别等于女
-
创建一个新的 List 集合,用于存储过滤以后符合条件的字符串
-
使用 List 中的 forEach(Lambda)遍历上面的原始 List 集合,
使用 Predicate 中的 and 和 test 方法判断每个元素
-
两个条件都为真才添加到新的 List 集合中
-
创建第 1 个 Consumer 接口,输出使用逗号分隔的第 0 个元素姓名
-
创建第 2 个 Consumer 接口,输出使用逗号分隔的第 1 个元素性别
-
使用 List 中的 forEach(Lambda)遍历,输出过滤后的新的集合
-
使用 Consumer 接口中的 andThen 和 accept 方法,输出每一个元素
package com.testjdk8.test.thread;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class DemoSupplier {
public static void main(String[] args) {
//从数组中创建一个 List 集合
List<String> list = Arrays.asList("张飞,男", "貂蝉,女", "曹操,男", "孙尚香,女", "小乔,女");
//创建第 1 个 Predicate 判断条件:使用逗号分隔的第 0 个元素姓名长度是 2
Predicate<String> pname = s -> s.split(",")[0].length() == 2;
//创建第 2 个 Predicate 判断条件:使用逗号分隔的第 1 个元素性别等于女
Predicate<String> pgender = s -> s.split(",")[1].equals("女");
//创建一个新的 List 集合
List<String> infos = new ArrayList<>();
//使用 Lamba 中的 forEach()遍历上面的 List 集合,使用 Predicate 中的 and 和 test 方法判断每个元素
list.forEach(s -> {
//两个都为真才添加到集合中
if (pname.and(pgender).test(s)) {
infos.add(s);
}
});
//创建第 1 个 Consumer 接口,输出使用逗号分隔的第 0 个元素姓名
Consumer<String> cname = s -> System.out.println("姓名:" + s.split(",")[0]);
//创建第 2 个 Consumer 接口,输出使用逗号分隔的第 1 个元素性别
Consumer<String> cgender = s -> System.out.println("性别:" + s.split(",")[1]);
//使用 Lamba 中的 forEach()遍历,输出过滤后的集合
infos.forEach(s -> {
//使用 Consumer 接口中的 andThen 和 accept 方法,每输出一个元素隔一条线
cname.andThen(cgender).accept(s);
System.out.println("---------------");
});
}
}
自己用的lambda表达式+stream流+函数式接口写的
package com.testjdk8.test.thread;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class DemoSupplier {
public static void main(String[] args) {
String[] arr = {"张飞,男", "貂蝉,女", "曹操,男", "孙尚香,女"};//这里的 s 表示数组中的每个元素
//创建第 1 个 Predicate 判断条件:使用逗号分隔的第 0 个元素姓名长度是 2
Predicate<String> predicate1 = str -> str.split(",")[0].length() == 2;
//创建第 2 个 Predicate 判断条件:使用逗号分隔的第 1 个元素性别等于女
Predicate<String> prodicate2 = str -> str.split(",")[1].equals("女");
//创建一个新的 List 集合,用于存储过滤以后符合条件的字符串
List<String> list = new ArrayList<>();
// 使用 List 中的 forEach(Lambda)遍历上面的原始 List 集合,
// 使用 Predicate 中的 and 和 test 方法判断每个元素
List<String> list1 = Arrays.asList(arr);
list=list1.stream()
.filter(f ->(predicate1.and(prodicate2).test(f)))
.collect(Collectors.toList());
list.forEach(
f -> System.out.println(f)
);
}
}
3.4,Fuction接口
3.4.1,apply()
package com.example1.demo1;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
//创建一个 Function 对象
Function<Integer, String> converter = i -> Integer.toString(i);
System.out.println("99 转成字符串的长度是:" + converter.apply(99).length());
System.out.println("1000 转成字符串的长度是:" + converter.apply(1000).length());
}
}
3.4.2,andThen()
package com.example1.demo1;
import java.util.Scanner;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
//用户输入一个字符串
System.out.println("请输入数字:");
Scanner input = new Scanner(System.in);
String str = input.nextLine();
//第 1 个函数将字符串转成整数
Function<String, Integer> f1 = s -> Integer.parseInt(s);
//第 2 个函数将整数乘以 10 返回
Function<Integer, Integer> f2 = i -> i * 10;
//调用 andThen 方法,并且输出结果
System.out.println("转成整数并乘以 10 以后的结果是:" + f1.andThen(f2).apply(str));
}
}
3.4.3,compose() 反转
package com.example1.demo1;
import java.util.Scanner;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
Function<String, String> f1 = s -> s.toUpperCase();
Function<String, String> f2 = s -> s.toLowerCase();
System.out.println("转成大写:" + f1.apply("Hello"));
System.out.println("转成小写:" + f2.apply("Hello"));
System.out.println("先转成大写,再转成小写:" + f1.andThen(f2).apply("Hello"));
System.out.println("先转成小写,再转成大写:" + f1.compose(f2).apply("Hello"));
}
}
3.4.4,function应用实例
需求说明:请使用 Function 进行函数拼接,按照顺序执行多个函数。操作依次为:1) 将字符串"赵丽颖,20"截取数字年龄部分,得到字符串;2) 将上一步的字符串转换成为 int 类型的数字;3) 将上一步的 int 数字累加 100,得到结果 int 数字。 开发步骤:1) 创建第 1 个 Function 对象,将字符串 20 取出,返回一个字符串2) 创建第 2 个 Function 对象,将字符串转成整数,返回整数3) 创建第 3 个 Function 对象,将整数加 100,返回计算结果4) 调用 andThen 方法 2 次,apply 方法应用字符串:“赵丽颖,20”,输出结果代码实现
package com.example1.demo1;
import java.util.Scanner;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
//创建第 1 个 Function 对象,将字符串 20 取出,返回一个字符串
Function<String, String> fun1 = s -> s.split(",")[1];
//创建第 2 个 Function 对象,将字符串转成整数,返回整数
Function<String, Integer> fun2 = s -> Integer.parseInt(s);
//创建第 3 个 Function 对象,将整数加 100,返回计算结果
Function<Integer, Integer> fun3 = num -> num + 100;
//调用 andThen 方法 2 次,apply 方法应用字符串,输出结果
System.out.println("计算结果:" + fun1.andThen(fun2).andThen(fun3).apply("赵丽颖,20"));
}
}
3.5,BinaryOperator 接口
3.5.1,apply()
package com.example1.demo1;
import java.util.Scanner;
import java.util.function.BinaryOperator;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
BinaryOperator<Integer> operator = (m, n) -> m + n;
System.out.println("计算结果是:" + operator.apply(3, 5));
}
}
3.5.2,静态方法 parallelPrefix()用于操作替换前一个数组元素
package com.example1.demo1;
import java.util.Arrays;
import java.util.Scanner;
import java.util.function.BinaryOperator;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
BinaryOperator<Integer> operator = (m, n) -> m + n;
Integer[] arr = {2, 1, 3, 5};
System.out.println("操作前的数组:" + Arrays.toString(arr));
Arrays.parallelPrefix(arr, operator);
System.out.println("操作后的数组:" + Arrays.toString(arr));
}
}
3.5.3,Comparator
package com.example1.demo1;
import java.util.Comparator;
import java.util.function.BinaryOperator;
public class Test {
public static void main(String[] args) {
//naturalOrder()是 Comparator 中的静态方法,即按数字的正常大小进行比较
BinaryOperator oper1 = BinaryOperator.minBy(Comparator.naturalOrder());
System.out.println("最小值是:" + oper1.apply(3,5));
//naturalOrder()是 Comparator 中的静态方法,即按字符串的正常大小进行比较
BinaryOperator oper2 = BinaryOperator.maxBy(Comparator.naturalOrder());
System.out.println("最大值是:" + oper2.apply("ABCD","xyz"));
}
}
3.6,UnaryOperator 接口
package com.example1.demo1;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.function.UnaryOperator;
public class Test {
public static void main(String[] args) {
//创建一个 UnaryOperator对象,
UnaryOperator operator = UnaryOperator.identity();
//调用 apply()方法,输出参数的值
System.out.println("输出与输出一样:" + operator.apply("abc"));
List nums = Arrays.asList(3, 10, 8, 2);
System.out.println("替换前:" + nums);
UnaryOperator <Integer>oper = x -> x * 2;
nums.replaceAll(oper);
System.out.println("替换后:" + nums);
List <String>names = Arrays.asList("Jack","Rose","Tom","NewBoy");
System.out.println("替换前:" + names);
names.replaceAll(s -> s.toUpperCase());
System.out.println("替换后:" + names);
}
}
常用的函数式接口小结
Supplier 提供数据者
T get();没有传入参数,有结果。
Consumer 消费数据者
void accept(T t); 传入数据,没有结果。
andThen()
Predicate 谓语
boolean test(T t); 对传入的数据逻辑判断
and()
or()
negate()
isEqual()
Function 函数
R apply(T t); 传入一个变量返回计算结果
andThen()
compose()
identity()
BinaryOperator 二元操作符
T apply(T t,T u); 传入两个参数返回一个结果
andThen()
继承于 BiFunction
UnaryOperator
继承于 Function
一元操作符
T apply(T t); 传入一个参数返回一个结果
andThen()
compose()
identity()
4,Optional类
为防止空指针异常
平时我们操作是
if(User!=null){
if(User.getAddress()!=null)
if(User.getAddress().getCountry()!=null)
if(User.getAddress().getCountry().getIsoCode()!=null)
String isocode=User.getAddress().getCountry().getIsoCode().toUpperCase()
}
Optional类可以防止空指针异常,代码如下
(1)User类
package com.example1.demo1;
public class User {
private String address;
User(){}
public User(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
(2)Test类
package com.example1.demo1;
import java.util.Optional;
public class Test {
public static void main(String[] args) {
User user=new User();
User user1=new User("南头");
String result= Optional.ofNullable(user)
.map(c -> user.getAddress())
.orElse("我在防止空指针");
String result1= Optional.ofNullable(user1)
.map(c -> user1.getAddress())
.orElse("我在防止空指针");
System.out.println(result);
System.out.println(result1);
}
}
5,Date类
5.1,instant
package com.example1.demo1;
import java.time.Clock;
import java.time.Instant;
import java.util.Date;
public class Test {
public static void main(String[] args) {
Clock clock=Clock.systemDefaultZone();
Long milis=clock.millis();
System.out.println(milis);
//instant类创建以前的data类
Instant instant=clock.instant();
Date date=Date.from(instant);
System.out.println(date.toString());
}
}
5.2,zoneId
package com.example1.demo1;
import java.time.ZoneId;
public class Test {
public static void main(String[] args) {
ZoneId zone1=ZoneId.of("Europe/Berlin");
System.out.println(zone1.getRules());
}
}
5.3,LocalDateTime
package com.example1.demo1;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneId;
public class Test {
public static void main(String[] args) {
LocalDateTime time=LocalDateTime.of(2020, Month.JUNE,8,21,22,22);
DayOfWeek dayOfWeek=time.getDayOfWeek();
System.out.println(dayOfWeek);
Month month=time.getMonth();
System.out.println(month);
}
}