- 在多线程方面,Lambda表达式的使用
- 不使用Lambda表达式的情况下,开启多线程的方式
/*
测试:开启多线程,打印数据
结论:不使用函数式编程带来冗余
*/
public class Demo01Runnable {
public static void main(String[] args) {
//使用Runnable的实现类,完成方法调用
RunnableImpl r = new RunnableImpl();
Thread t = new Thread(r);
t.start();
//使用匿名内部类简化编码
Runnable r2 = new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类的方式开启多线程...run...");
}
};
new Thread(r2).start();
//进一步简化
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类的方式开启多线程2...run...");
}
}).start();
}
}
/*
Lambda表达式的标准格式:
三部分组成:一些参数,一个箭头,一段代码
格式:
(参数列表)->{一些重写方法的代码}
*/
/*
Lambda表达式是可推导,可省略的
省略的内容:
1.(参数列表):括号中的参数列表的数据类型可以省略
2.(参数列表):若括号中参数只有一个,那么类型和()都可以省略
3.{一些代码}:若{}中的代码只有一行,无论是否有返回值,都可以省略 {},return,分号
注意:必须一起省略
*/
public class Demo02Lambda {
public static void main(String[] args) {
//使用匿名内部类的方式实现多线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类...run...");
}
}).start();
//使用Lambda表达式实现多线程
new Thread(()->{
System.out.println("Lambda表达式...run...");
}).start();
//省略的Lambda表达式
new Thread(()->System.out.println("Lambda表达式...run...")).start();
}
}
- 自定义接口,并使用Lambda表达式的方式调用
public interface Cook {
public abstract void makeFood();
}
/*
练习:给定一个Cook接口,内含唯一抽象方法makeFood,无参无返回值。
使用Lambda的格式调用invokeCook方法,打印数据
*/
public class Demo01Cook {
public static void main(String[] args) {
//匿名内部类的方式
invokeCook(new Cook() {
@Override
public void makeFood() {
System.out.println("makeFood1...");
}
});
//Lambda表达式
invokeCook(()->{
System.out.println("makeFood2...");
});
//省略的Lambda表达式
invokeCook(()->System.out.println("makeFood3..."));
}
public static void invokeCook(Cook cook){
cook.makeFood();
}
}
- 实现使用Lambda表达式,对对象中某个属性进行排序的功能
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 使用Lambda表达式的方式对JavaBean进行排序
import java.util.Arrays;
/*
Lambda表达式有参数有返回值练习:使用数组存储多个Person对象,
对数组中的Person对象按照age升序(前-后)排序
*/
public class Demo01Arrays {
public static void main(String[] args) {
Person[] arr = {
new Person("yorick",23),
new Person("tom",12),
new Person("jerry",16)
};
//使用匿名内部类的方式
/* Arrays.sort(arr, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});*/
//使用Lambda表达式
/* Arrays.sort(arr,(Person o1,Person o2)->{
return o1.getAge()-o2.getAge();
});*/
//省略的Lambda表达式
Arrays.sort(arr,(o1,o2)->o1.getAge()-o2.getAge());
for (Person person : arr) {
System.out.println(person);
}
}
}
- 自定义接口,使用Lambda表达式调用,有参数的练习
public interface Calculator {
public abstract Integer calc(int a,int b);
}
/*
Lambda有参数有返回值练习:给定一个Calculator接口,内含抽象方法calc计算两数之和,
使用Lambda表达式调用invokeCalc方法
*/
public class Demo01Calculator {
public static void main(String[] args) {
//使用匿名内部类
invokeCalc(10, 20, new Calculator() {
@Override
public Integer calc(int a, int b) {
return a+b;
}
});
//使用Lambda表达式
invokeCalc(120,130,(int a,int b)->{
return a+b;
});
//简化的Lambda表达式
invokeCalc(220,230,(a,b)->a+b);
}
public static void invokeCalc(int a,int b,Calculator calculator){
int result = calculator.calc(a,b);
System.out.println(result);
}
}
常用函数式接口
- Supplier接口
/*
Supplier<T>接口仅包含一个无参方法:T get() 用于获取一个泛型参数指定类型的对象数据。
用处:
该接口称为生产型接口,指定接口的泛型,get方法就会生成什么类型的数据
*/
public class Demo01Supplier {
public static void main(String[] args) {
String result = getString(()->"你好");
System.out.println(result);
}
public static String getString(Supplier<String> supplier){
return supplier.get();
}
}
import java.util.function.Supplier;
/*
练习:使用Supplier接口求数组元素的最大值
*/
public class Demo02SupplierGetMax {
public static void main(String[] args) {
//定义一组数据
Integer[] arr = {10,23,-10,0,66};
//调用getMax方法,方法的参数Supplier是一个函数式接口
Integer result = getMax(()->{
int max = arr[0];
for (Integer i : arr) {
if(i>max){
max = i;
}
}
return max;
});
System.out.println(result);
}
public static Integer getMax(Supplier<Integer> supplier){
return supplier.get();
}
}
- Consumer接口
import java.util.function.Consumer;
/*
Consumer<T>接口与Supplier接口相反,包含抽象方法 void accept(T t),用于消费一个指定泛型的数据
用途:
Consumer是一个消费型接口,泛型是什么类型就可以通过accept方法消费什么类型的数据,
如何消费可以自己在Lambda表达式中定义
*/
public class Demo01Consumer {
public static void main(String[] args) {
method("yorick",(String name)->{
System.out.println(name);
//反转字符串
String reName = new StringBuffer(name).reverse().toString();
System.out.println(reName);
});
}
public static void method(String name,Consumer<String> consumer){
consumer.accept(name);
}
}
import java.util.function.Consumer;
/*
Consumer的默认方法andThen
作用:需要两个Consumer接口,把两个Consumer接口组合到一起,再对数据进行消费
若con1连接con2,则con1先消费数据,con2再消费数据
*/
public class Demo02andThen {
public static void main(String[] args) {
method("Yorick",
(name)->{
System.out.println(name.toUpperCase());
},
(name)->{
System.out.println(name.toLowerCase());
});
}
public static void method(String name, Consumer<String> consumer1,Consumer<String> consumer2){
//不使用andThen方法
/*consumer1.accept(name);
consumer2.accept(name);*/
//使用andThen方法
//consumer1.andThen(consumer2).accept(name);
//使用andThen方法 先消费consumer2
consumer2.andThen(consumer1).accept(name);
}
}
import java.util.function.Consumer;
/*
练习:
使用Consumer接口,将字符串数组中多条信息按照"姓名:xx,性别:xx"的格式打印
*/
public class Demo03StringSplit {
public static void main(String[] args) {
//定义一个字符串数组
String[] arr = {"yorick,boy","tom,boy","lucy,girl"};
//Lambda表达式实现功能
method(arr,
(message)->{
String name = message.split(",")[0];
System.out.print("姓名:"+name);
},
(message)->{
String gender = message.split(",")[1];
System.out.println(",性别:"+gender);
});
}
public static void method(String[] arr, Consumer<String> consumer1,Consumer<String> consumer2){
for (String message : arr) {
consumer1.andThen(consumer2).accept(message);
}
}
}
- Predicate接口
import java.util.function.Predicate;
/*
Predicate<T>接口,包含一个抽象方法 boolean test(T t) 用来对指定数据类型数据进行判断的方法
作用:对某种数据类型的数据进行判断,结果返回一个boolean值
结果:符合条件,true;不符合条件,false
*/
public class Demo01Predicate {
public static void main(String[] args) {
String str = "yorick";
/*Boolean result = checkString(str,(String s)->{
return s.length()>5;
});*/
//简化
Boolean result = checkString(str,s->s.length()>5);
System.out.println(result);
}
public static Boolean checkString(String str, Predicate<String> predicate){
return predicate.test(str);
}
}
import java.util.function.Predicate;
/*
案例:
使用and连接两个Predicate
满足:1.长度大于5
2.包含字母y
*/
public class Demo02PredicateAnd {
public static void main(String[] args) {
String str = "yorick";
Boolean result = checkString(str,
(String s)->{
//长度大于5
return s.length()>5;
},(String s)->{
//包含字母y
return s.contains("y");
});
System.out.println(result);
}
public static Boolean checkString(String str, Predicate<String> predicate1,Predicate<String> predicate2){
return predicate1.and(predicate2).test(str);//等价于 return predicate1.test(str) && predicate2.test(str);
}
}
import java.util.ArrayList;
import java.util.function.Predicate;
/*
练习:集合信息筛选,通过Predicate接口实现对字符串数组进行筛选的功能,
需要同时满足的条件:
1.必须为male
2.姓名字母5个以上
*/
public class Demo03PracticeTest {
public static void main(String[] args) {
//定义一个字符串数组
String[] str = {"yorick,male","tom,male","torasa,female","jackson,male"};
//调用方法进行筛选
ArrayList<String> list = filter(str, (String s) -> {
return s.split(",")[0].length() > 5;
}, (String s) -> {
return s.split(",")[1].equals("male");
});
//遍历结果
for (String s : list) {
System.out.println(s);
}
}
public static ArrayList<String> filter(String[] str, Predicate<String> pre1,Predicate<String> pre2){
ArrayList<String> result = new ArrayList<>();
for (String s : str) {
boolean flag = pre1.and(pre2).test(s);
if(flag == true){
result.add(s);
}
}
return result;
}
}
- Function接口
import java.util.function.Function;
/*
Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据。
前者称为前置条件,后者称为后置条件
Function接口的主要抽象方法为:R apply(T t) 根据类型T的参数获取类型R的结果
*/
//将String类型转换为Integer类型
public class Demo01Function {
public static void main(String[] args) {
StringToInteger("233",s->Integer.parseInt(s));
}
public static void StringToInteger(String s, Function<String,Integer> fun){
Integer result = fun.apply(s);
System.out.println(result);
}
}
import java.util.function.Function;
/*
Function接口的默认方法andThen用来进行组合操作
需求:把String类型的"233"转换为Integer类型并结果+10,
把增加之后的Integer类型的数据再转换为String类型
*/
public class Demo02AndThen {
public static void main(String[] args) {
/*change("233",(String s)->{
return Integer.parseInt(s)+10;
},(Integer i)->{
return i+"";
});*/
//简化Lambda表达式
change("233",s->Integer.parseInt(s)+10,i->i+"");
}
public static void change(String s, Function<String,Integer> fun1,Function<Integer,String> fun2){
String result = fun1.andThen(fun2).apply(s);
System.out.println(result);
}
}
网友评论