Lambda表达式是函数式编程的风格,是为了给SAM接口的变量和形参赋值的一种语法。
目的:减少代码的冗余,增加可读性。
示例1:
开启一个线程,这个线程的任务:打印“hello”
要求用实现Runnable接口的方式来创建多线程
Runnable接口符合SAM特征: public abstract void run();
Runnable接口唯一的抽象方法就是public abstract void run();
public class Test01 {
@Test
public void test05(){
//使用Lambda表达式
new Thread(()->System.out.println("hello")).start();
}
@Test
public void test04(){
//匿名内部类,匿名对象
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("hello");
}
}).start();
}
@Test
public void test03(){
//匿名内部类,匿名对象
Thread t = new Thread(new Runnable(){
@Override
public void run() {
System.out.println("hello");
}
});
t.start();
}
@Test
public void test02(){
//匿名内部类,对象有名字
Runnable my = new Runnable(){
@Override
public void run() {
System.out.println("hello");
}
};
Thread t = new Thread(my);
t.start();
}
@Test
public void test01(){
// 非Lambda表达式方式实现,并且有名字的实现类实现
MyRunnable my = new MyRunnable();
Thread t = new Thread(my);
t.start();
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("hello");
}
}
示例2:
public class Test02 {
@Test
public void test04(){
Student[] arr = new Student[5];
arr[0] = new Student(1,"zhangsan");
arr[1] = new Student(2,"lisi");
arr[2] = new Student(3,"wangwu");
arr[3] = new Student(4,"zhaoliu");
arr[4] = new Student(5,"qianqi");
Arrays.sort(arr, (o1, o2)-> o1.getName().compareTo(o2.getName()));//按照元素的姓名定制排序
for (Student student : arr) {
System.out.println(student);
}
}
@Test
public void test03(){
Student[] arr = new Student[5];
arr[0] = new Student(1,"zhangsan");
arr[1] = new Student(2,"lisi");
arr[2] = new Student(3,"wangwu");
arr[3] = new Student(4,"zhaoliu");
arr[4] = new Student(5,"qianqi");
Arrays.sort(arr, new Comparator(){
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
});//按照元素的姓名定制排序
for (Student student : arr) {
System.out.println(student);
}
}
@Test
public void test02(){
Student[] arr = new Student[5];
arr[0] = new Student(1,"zhangsan");
arr[1] = new Student(2,"lisi");
arr[2] = new Student(3,"wangwu");
arr[3] = new Student(4,"zhaoliu");
arr[4] = new Student(5,"qianqi");
Arrays.sort(arr, new NameComparator());//按照元素的姓名定制排序
for (Student student : arr) {
System.out.println(student);
}
}
@Test
public void test01(){
Student[] arr = new Student[5];
arr[0] = new Student(1,"zhangsan");
arr[1] = new Student(2,"lisi");
arr[2] = new Student(3,"wangwu");
arr[3] = new Student(4,"zhaoliu");
arr[4] = new Student(5,"qianqi");
Arrays.sort(arr);//按照元素的自然顺序排列
for (Student student : arr) {
System.out.println(student);
}
}
}
class NameComparator implements Comparator{
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
}
class Student implements Comparable{
private int id;
private String name;
public Student(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Student() {
super();
}
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;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
@Override
public int compareTo(Student o) {
return this.id - o.id;
}
}
它的抽象方法有一个特征: 有参无返回值 例如:void accept(T t)
它的抽象方法有一个特征: 无参有返回值 例如:T get()
它的抽象方法有一个特征: 有参有返回值,但是返回值类型是boolean 例如:boolean test(T t)
它的抽象方法有一个特征: 有参有返回值 例如: R apply(T t)
Consumer 抽象方法 void accept(T t)
(1)BiConsumer
(2)
DoubleConsumer void accept(double value) 接收一个double值
IntConsumer void accept(int value) 接收一个int值
LongConsumer void accept(long value) 接收一个long值
(3)
ObjDoubleConsumer void accept(T t, double value) 接收一个对象和一个double值
ObjIntConsumer void accept(T t, int value) 接收一个对象和一个int值
ObjLongConsumer void accept(T t, long value) 接收一个对象和一个long值
*
*
(2)Bi开头,传两个参数 Binary(二元的)
(3)xxConsumer,前面的xx代表形参类型
(2)xxSupplier说明返回xx类型的结果
(3)供给型接口的抽象方法都是无参的
Predicate 抽象方法 boolean test(T t)
(2)判断型接口抽象方法的返回值类型是固定的,是boolean
(3)xxPredicate,说明形参是xx类型的
经典代表:
Function 抽象方法 R apply(T t)
延伸代表:
(1)UnaryOperator T apply(T t) 接收一个T类型对象,返回一个T类型对象结果
(2)
DoubleFunction R apply(double value) 接收一个double值,返回一个R类型对象
IntFunction R apply(int value) 接收一个int值,返回一个R类型对象
LongFunction R apply(long value) 接收一个long值,返回一个R类型对象
(3)
ToDoubleFunction double applyAsDouble(T value) 接收一个T类型对象,返回一个double
ToIntFunction int applyAsInt(T value) 接收一个T类型对象,返回一个int
ToLongFunction long applyAsLong(T value) 接收一个T类型对象,返回一个long
(4)
DoubleToIntFunction int applyAsInt(double value) 接收一个double值,返回一个int结果
DoubleToLongFunction long applyAsLong(double value) 接收一个double值,返回一个long结果
IntToDoubleFunction double applyAsDouble(int value) 接收一个int值,返回一个double结果
IntToLongFunction long applyAsLong(int value) 接收一个int值,返回一个long结果
LongToDoubleFunction double applyAsDouble(long value) 接收一个long值,返回一个double结果
LongToIntFunction int applyAsInt(long value) 接收一个long值,返回一个int结果
(5)
DoubleUnaryOperator double applyAsDouble(double operand) 接收一个double值,返回一个double
IntUnaryOperator int applyAsInt(int operand) 接收一个int值,返回一个int结果
LongUnaryOperator long applyAsLong(long operand) 接收一个long值,返回一个long结果
(6)BiFunction
(7)BinaryOperator T apply(T t, T u) 接收两个T类型对象,返回一个T类型对象结果
(8) ToDoubleBiFunction
ToIntBiFunction
ToLongBiFunction
(9) DoubleBinaryOperator double applyAsDouble(double left, double right) 接收两个double值,返回一个double结果
IntBinaryOperator int applyAsInt(int left, int right) 接收两个int值,返回一个int结果
LongBinaryOperator long applyAsLong(long left, long right) 接收两个long值,返回一个long结果
总结:(1)以Unary开头的,表示一元的,泛型的类型只有一个,形参和返回值都是同一种类型
(2)xxFunction,说明形参的类型是xx类型的
(3)toXXFunction,说明返回值类型是xx类型
(4)xxToyyFunction,说明形参的类型是xx类型的,返回值类型是yy类型
(5)xxUnary开头的,表示一元,形参类型和返回值类型都是xx
(6)Bi开头,表示二元,形参类型是2个
(7)BinaryOperator,既是Bi开头表示两个形参,又是Operator结尾,表示形参和返回值类型是一样
(8)toXXBi开头的,表返回值类型是xx,并且形参是两个
(9)xxBinaryOperator,表示两个形参,又是Operator结尾,表示形参和返回值类型是一样
Lambda表达式是给函数式接口(SAM接口)的变量或形参赋值的表达式。
(2){Lambda体}就是实现SAM接口的抽象方法的方法体
(3)->称为Lambda操作符,由“减号”和“大于号”构成,中间不能有空格
public class Test03Lambda {
@Test
public void test01(){
//使用Lambda表达式给Runnable接口的形参赋值,这个线程要打印“AT"
//构造器:new Thread(Runnable target)
//现在要用Lambda表达式给Runnable类型的target形参赋值
/*
* 写好一个Lambda表达式关注两个事情:
* (1)抽象方法长什么样 -->形参列表怎么写
* public void run()
* (2)抽象方法怎么实现,即这个抽象方法要做什么事情 -->Lambda体
*/
//new Thread(() -> {System.out.println("AT");}).start();
//优化
new Thread(() -> System.out.println("AT")).start();
}
@Test
public void test02(){
/*
* 在Java8版本,给Iterable这个接口增加一个默认方法
* default void forEach(Consumer super T> action) 这个方法可以遍历容器中的元素,做xx事情
*
* Collection接口继承了Iterable接口,说明Collection系列的集合都有这个方法,例如:ArrayList
*
*/
ArrayList list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("java");
list.add("at");
/*
* forEach方法的形参是Consumer类型,它是消费型接口的类型,是SAM接口,就可以使用Lambda表达式赋值
* (1)接口的抽象方法
* void accept(T t) 这里方法名不重要,只看返回值类型和形参列表
* (2)要如何实现这个抽象方法,例如:我这里要打印元素
*/
// list.forEach((String str) -> {System.out.println(str);});
// 优化
// list.forEach((String str) -> System.out.println(str));
//再优化
list.forEach((str) -> System.out.println(str));
//再优化
list.forEach(str -> System.out.println(str));
}
@Test
public void test03(){
//从集合中删除字符个数超过6个的
ArrayList list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("java");
list.add("at");
/*
* Java8中Collection接口增加了一个方法
* default boolean removeIf(Predicate super E> filter)
* 这个方法的形参是Predicate判断型接口,是SAM接口,可以使用Lambda表达式赋值
*
* Predicate判断型接口
* (1)抽象方法
* boolean test(T t)
* (2)如何实现抽象方法
* 这里判断条件是 字符个数>6
*/
/* list.removeIf((String str) -> {
if(str.length()>6){
return true;
}else{
return false;
}
});*/
//代码优化
list.removeIf((String str) -> {return str.length()>6;});
//再优化
list.removeIf(str -> str.length()>6);
}
}
public void test01(){
/*
* Java8中,有一个新的类:Stream类型,它代表一个数据加工流
* java.util.stream.Stream接口
* static Stream generate(Supplier s)
*
* 这个静态方法的形参:Supplier供给型接口的类型,SAM接口,可以使用Lambda表达式赋值
* 接口的静态方法通过“接口名.静态方法”调用
*
* Supplier接口
* (1)抽象方法 T get()
* (2)抽象方法如何实现
* 例如:在抽象方法中实现,随机产生一个小数[0,1),返回值类型double
*/
// Stream stream = Stream.generate(() -> {return Math.random();});
//优化
Stream stream = Stream.generate(() -> Math.random());
/*
* 为了看效果,我再调用Stream接口的void forEach(Consumer super T> action)
* 这个方法形参是Consumer消费型接口类型,SAM接口,也可以使用Lambda表达式赋值
*
* Consumer消费型接口:
* (1)抽象方法
* void accept(T t)
* (2)如何实现抽象方法
* 例如:打印流中的元素
*
*/
// stream.forEach((Double num) -> {System.out.println(num);});
//优化
stream.forEach(num -> System.out.println(num));
}
JDK1.8时Map接口增加了一个方法:
public class Test05Lambda3 {
@Test
public void test01(){
HashMap map = new HashMap<>();
map.put("张三", new Employee("张三", 8000));
map.put("李四", new Employee("李四", 9000));
map.put("王五", new Employee("王五", 12000));
map.put("赵六", new Employee("赵六", 11000));
//把原来薪资低于10000元的,修改为薪资为10000元,其他的不变
/*
* replaceAll(BiFunction super K,? super V,? extends V> function)
*
* replaceAll的形参是BiFunction接口类型,SAM接口,可以使用Lambda表达式赋值
*
* BiFunction接口:
* (1)抽象方法
* R apply(T t, U u)
* (2)如何实现抽象方法
* 例如:把原来value对象的薪资<10000元的替换(覆盖)为薪资是10000元
*
* 如果抽象方法有返回值,那么实现抽象方法时,需要return语句。
* 这里看返回值类型是V类型,是value的类型
*/
map.replaceAll((String key,Employee emp) -> {
if(emp.getSalary()<10000){
emp.setSalary(10000);
}
return emp;
});
//优化
map.replaceAll((key,emp) -> {
if(emp.getSalary()<10000){
emp.setSalary(10000);
}
return emp;
});
}
}
class Employee {
private String name;
private double salary;
public Employee(String name, double salary) {
super();
this.name = name;
this.salary = salary;
}
public Employee() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + "]";
}
}
public class TestDefineFunctionalInterface {
public static void main(String[] args) {
//IntCalc tools形参,函数式接口,可以Lambda表达式赋值
/*
* (1)抽象方法:int cal(int a , int b);
* (2)如何实现抽象方法
* 例如:求a+b的和
*/
getProduct(1,2, (int a , int b) -> {return a+b;});//new了一个IntCalc的实现类的对象,而且实现了IntCalc抽象方法
getProduct(1,2, (a ,b) ->a*b);
}
//2、在测试类中定义public static void getProduct(int a , int b ,IntCalc tools),
//该方法的预期行为打印使用tools的cal(a,b)的计算结果
public static void getProduct(int a , int b ,IntCalc tools){
int result = tools.cal(a, b);
System.out.println("结果:" + result);
}
}
//1、定义一个函数式接口IntCalc,其中抽象方法int cal(int a , int b),使用注解@FunctionalInterface
@FunctionalInterface
interface IntCalc{
int cal(int a , int b);
}
lambda表达式是用来简化匿名内部类的一种函数式编程的语法。
只有SAM接口才能使用lambda表达式
只有当lambda表达式满足一些特殊情况时,才能使用方法引用和构造器引用。
public class TestFunctionReference {
@Test
public void test06(){
new Thread(() -> System.out.println("hello")).start();//不能使用方法引用来优化,因为“hello”加在了println里面,就变成了有参。对象::方法,这里面方法之后不跟东西
}
@Test
public void test05(){
//调用createArray这个方法,创建一个2的n次方长度的数组
/*
* public R[] createArray(Function fun,int length)
* 第一个参数:Function接口 ,是SAM接口,可以赋值为Lambda表达式
* Function接口的抽象方法: R apply(T t)
*
* R[] apply(Integer i)
* 如何实现,创建一个长度为i的R类型的数组
*
*/
// String[] arr = createArray((Integer i) -> new String[i], 10);
//优化为
String[] arr = createArray(String[]::new, 10);
System.out.println(Arrays.toString(arr));
System.out.println(arr.length);
}
/*
* 模仿HashMap的源码实现的一个方法,功能是,可以创建一个2的n次方长度的数组
* 例如:这个length是你希望的数组的长度,但是它可能不是2的n次方,那么我会对length进行处理,纠正为一个2的n次方长度,并且创建这个数组
*/
public R[] createArray(Function fun,int length){
int n = length - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
length = n < 0 ? 1 : n + 1;
return fun.apply(length);
}
@Test
public void test04(){
//lambda表达式也可以用于给SAM接口的变量赋值
/*
* Supplier 接口的抽象方法 T get()
* 如何实现这个抽象方法,例如:这里要new一个String的空对象
*/
// Supplier s = () -> new String();
//就可以使用构造器引用,来创建对象
Supplier s = String::new;
}
@Test
public void test03(){
String[] arr = {"hello","Hi","world","chailinyan","at"};
//不区分大小写的排序
/*
* public static void sort(T[] a, Comparator super T> c)
* 第二个形参:Comparator接口,SAM接口,赋值为Lambda表达式
*
* Comparator接口的抽象方法:
* int compare(String s1, String s2)
* 如何实现?不区分大小写比较字符串
*/
// Arrays.sort(arr, (s1,s2) -> s1.compareToIgnoreCase(s2));
/*
* Comparator接口 int compare(String s1, String s2)
* String类的 int compareToIgnoreCase(String str) 此处,s1正好是调用compareToIgnoreCase的对象,s2是给它的参数
*/
//使用方法引用优化
Arrays.sort(arr, String::compareToIgnoreCase);
System.out.println(Arrays.toString(arr));
}
@Test
public void test02(){
/*
* Stream的
* public static Stream generate(Supplier s)
* 形参是Supplier接口类型,赋值为Lambda表达式
*
* (1)抽象方法 T get()
* (2)如何实现, 用Math.random()随机产生一个[0,1)范围的数
*/
// Stream stream = Stream.generate(() -> Math.random());
/*
* Supplier接口的抽象方法 T get() Double get()
* 调用的是 double Math.random()
*/
//使用方法引用
Stream stream = Stream.generate(Math::random);
stream.forEach(System.out::println);
}
@Test
public void test01(){
List list = Arrays.asList(1,2,3,4,5);
/*
* default void forEach(Consumer super T> action)
* 形参的类型是Consumer接口,可以使用Lambda表达式赋值
* Consumer void accept(T t)
*
*/
//list.forEach(num -> System.out.println(num));
/*
* (1)这里的lambda表达式是通过调用一个现有的方法来完成的,是out对象的println()方法来完成
* (2)Consumer public void accept(T t)
* PrintStream类的out对象 public void println(Object x)
*/
list.forEach(System.out::println);
}
}
StreamAPI:
public void test01(){
ArrayList list= new ArrayList<>();
list.add(new Employee(1,"张三"));
list.add(new Employee(1,"张三"));
Stream stream = list.stream();
stream = stream.distinct();//处理,中间操作 //不会修改数据源,只会把统计结果显示出来
long count = stream.count();//统计个数 终结操作
System.out.println(count);
System.out.println("over");
System.out.println("--------------------");
//重新遍历list
for (Employee employee : list) {
System.out.println(employee);
}
}
Stream接口:
集合对象.stream()
Arrays.stream(数组对象)
Stream.of(...)
public class Test07StreamCreate {
@Test
public void test06(){
/*
* Stream iterate(T seed, UnaryOperator f)
* UnaryOperator接口,SAM接口,抽象方法:
*
* UnaryOperator extends Function
* T apply(T t)
*/
Stream stream = Stream.iterate(1, num -> num+=2);
// stream = stream.limit(10);
stream.forEach(System.out::println);
}
@Test
public void test05(){
Stream stream = Stream.generate(Math::random);
stream.forEach(System.out::println);
}
@Test
public void test04(){
Stream stream = Stream.of(1,2,3,4,5);
stream.forEach(System.out::println);
}
@Test
public void test03(){
String[] arr = {"hello","world"};
Stream stream = Arrays.stream(arr);
}
@Test
public void test02(){
int[] arr = {1,2,3,4,5};
IntStream stream = Arrays.stream(arr);
}
@Test
public void test01(){
List list = Arrays.asList(1,2,3,4,5);
//JDK1.8中,Collection系列集合增加了方法
Stream stream = list.stream();
}
}
public class Test08StreamMiddle {
@Test
public void test12(){
String[] arr = {"hello","world","java"};
Stream flatMap = Arrays.stream(arr)
.flatMap(t -> Stream.of(t.split("|")));//Function接口抽象方法 R apply(T t) 现在的R是一个Stream
flatMap.forEach(System.out::println);
}
@Test
public void test11(){
String[] arr = {"hello","world","java"};
Arrays.stream(arr)
.map(t->t.toUpperCase())
.forEach(System.out::println);
}
@Test
public void test10(){
Stream.of(1,2,3,4,5)
.map(t -> t+=1)//Function接口抽象方法 R apply(T t)
.forEach(System.out::println);
}
@Test
public void test09(){
//希望能够找出前三个最大值,前三名最大的,不重复
Stream.of(11,2,39,4,54,6,2,22,3,3,4,54,54)
.distinct()
.sorted((t1,t2) -> -Integer.compare(t1, t2))//Comparator接口 int compare(T t1, T t2)
.limit(3)
.forEach(System.out::println);
}
@Test
public void test08(){
long count = Stream.of(1,2,3,4,5,6,2,2,3,3,4,4,5)
.distinct()
.peek(System.out::println) //Consumer接口的抽象方法 void accept(T t)
.count();
System.out.println("count="+count);
}
@Test
public void test07(){
Stream.of(1,2,3,4,5,6,2,2,3,3,4,4,5)
.skip(5)
.distinct()
.filter(t -> t%3==0)
.forEach(System.out::println);
}
@Test
public void test06(){
Stream.of(1,2,3,4,5,6,2,2,3,3,4,4,5)
.skip(5)
.forEach(System.out::println);
}
@Test
public void test05(){
Stream.of(1,2,2,3,3,4,4,5,2,3,4,5,6,7)
.distinct() //(1,2,3,4,5,6,7)
.filter(t -> t%2!=0) //(1,3,5,7)
.limit(3)
.forEach(System.out::println);
}
@Test
public void test04(){
Stream.of(1,2,3,4,5,6,2,2,3,3,4,4,5)
.limit(3)
.forEach(System.out::println);
}
@Test
public void test03(){
Stream.of(1,2,3,4,5,6,2,2,3,3,4,4,5)
.distinct()
.forEach(System.out::println);
}
@Test
public void test02(){
Stream.of(1,2,3,4,5,6)
.filter(t -> t%2==0)
.forEach(System.out::println);
}
@Test
public void test01(){
//1、创建Stream
Stream stream = Stream.of(1,2,3,4,5,6);
//2、加工处理
//过滤:filter(Predicate p)
//把里面的偶数拿出来
/*
* filter(Predicate p)
* Predicate是函数式接口,抽象方法:boolean test(T t)
*/
stream = stream.filter(t -> t%2==0);
//3、终结操作:例如:遍历
stream.forEach(System.out::println);
}
}
创建:一步
public class Test09StreamEnding {
@Test
public void test14(){
List list = Stream.of(1,2,4,5,7,8)
.filter(t -> t%2==0)
.collect(Collectors.toList());
System.out.println(list);
}
@Test
public void test13(){
Optional reduce = Stream.of(1,2,4,5,7,8)
.reduce((t1,t2) -> t1>t2?t1:t2);//BinaryOperator接口 T apply(T t1, T t2)
System.out.println(reduce);
}
@Test
public void test12(){
Integer reduce = Stream.of(1,2,4,5,7,8)
.reduce(0, (t1,t2) -> t1+t2);//BinaryOperator接口 T apply(T t1, T t2)
System.out.println(reduce);
}
@Test
public void test11(){
Optional max = Stream.of(1,2,4,5,7,8)
.max((t1,t2) -> Integer.compare(t1, t2));
System.out.println(max);
}
@Test
public void test10(){
Optional opt = Stream.of(1,2,4,5,7,8)
.filter(t -> t%3==0)
.findFirst();
System.out.println(opt);
}
@Test
public void test09(){
Optional opt = Stream.of(1,2,3,4,5,7,9)
.filter(t -> t%3==0)
.findFirst();
System.out.println(opt);
}
@Test
public void test08(){
Optional opt = Stream.of(1,3,5,7,9).findFirst();
System.out.println(opt);
}
@Test
public void test04(){
boolean result = Stream.of(1,3,5,7,9)
.anyMatch(t -> t%2==0);
System.out.println(result);
}
@Test
public void test03(){
boolean result = Stream.of(1,3,5,7,9)
.allMatch(t -> t%2!=0);
System.out.println(result);
}
@Test
public void test02(){
long count = Stream.of(1,2,3,4,5)
.count();
System.out.println("count = " + count);
}
@Test
public void test01(){
Stream.of(1,2,3,4,5)
.forEach(System.out::println);
}
}
Optional实际上是个容器,它是一个装一个对象的容器。这个对象可能是个空,可能是非空。
public class TestOptional {
@Test
public void test9(){
String str = "hello";
Optional opt = Optional.ofNullable(str);
Optional opt2 = opt.filter(s->s.length()>5);
System.out.println(opt2);
}
@Test
public void test8(){
String str = null;
Optional opt = Optional.ofNullable(str);
String string = opt.orElseThrow(()->new RuntimeException("值不存在"));
System.out.println(string);
}
@Test
public void test7(){
String str = null;
Optional opt = Optional.ofNullable(str);
String string = opt.orElseGet(String::new);
System.out.println(string);
}
@Test
public void test6(){
String str = "hello";
Optional opt = Optional.ofNullable(str);
String string = opt.orElse("at");
System.out.println(string);
}
@Test
public void test5(){
String str = null;
Optional opt = Optional.ofNullable(str);
// System.out.println(opt.get());//java.util.NoSuchElementException: No value present
}
@Test
public void test4(){
String str = "hello";
Optional opt = Optional.of(str);
String string = opt.get();
System.out.println(string);
}
@Test
public void test3(){
String str = null;
Optional opt = Optional.ofNullable(str);
System.out.println(opt);
}
@Test
public void test2(){
String str = "hello";
Optional opt = Optional.of(str);
System.out.println(opt);
}
@Test
public void test1(){
ArrayList list = new ArrayList<>();
list.add(new Student("张三", 23));
//...
//取出流中第一个年龄大于30岁的学生
Optional opt = list.stream()
.filter(s -> s.getAge()>30)
.findFirst();
//打印该学生的年龄
Student stu = opt.orElse(new Student());
System.out.println("学生的年龄:" + stu.getAge());
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
}
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 "Student [name=" + name + ", age=" + age + "]";
}
}