public class Employe {
private String name;
private int age;
private double salary;
public Employe() {
}
public Employe(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
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;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employe{" +
"name='" + name + '\'' +
", age=" + age +
", salary=" + salary +
'}';
}
}
Lambda 是一个匿名函数,可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。Java8引入了一个新的操作符 “->” 该操作符称为箭头符或lambda 操作符,箭头操作符将 Lambda 表达式拆分成两部分:左侧:Lambda 表达式的参数列表;右侧:Lambda 表达式中所需要执行的功能,即 Lambda 体;
public class TestLambda {
//原来匿名内部类
@Test
public void test1(){
Comparator com = new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
TreeSet ts = new TreeSet<>(com);
}
//Lambda表达式
@Test
public void test2(){
Comparator com = (o1, o2) -> Integer.compare(o1, o2);
TreeSet ts = new TreeSet<>(com);
}
}
/**
* Lambda表达式练习
*/
public class TestLambda1 {
List emps = Arrays.asList(
new Employe("张三", 18,9999.99),
new Employe("李四", 38,5555.99),
new Employe("王五", 50,6666.66),
new Employe("赵六", 16,3333.33),
new Employe("田七", 10,7777.77),
new Employe("田八", 10,7777.77)
);
//需求:按员工年龄排序,年龄相同按姓名排序
@Test
public void test1(){
Collections.sort(emps, (x, y) -> {
if (x.getAge() == y.getAge()){
return x.getName().compareTo(y.getName());
}else{
return -Integer.compare(x.getAge(),y.getAge());
}
});
emps.forEach(System.out::println);
}
}
/**
* java8 内置的四大核心函数式接口
*
* 1.Consumer:消费型接口
* void accept(T t);
*
* 2.Supplier: 供给型接口
* T get();
*
* 3.Function:函数型接口
* R apply(T t);
*
* 4.Predicate:断言型接口
* boolean test(T t);
*
*/
public class TestLambda3 {
//Consumer:消费型接口
@Test
public void test1(){
happy(1000, m-> System.out.println("吃饭消费:"+m));
}
public void happy(double money, Consumer con){
con.accept(money);
}
//Supplier: 供给型接口
@Test
public void test2(){
List list = getNumList(10, () -> (int)(Math.random() * 100));
list.forEach(System.out::println);
}
//需求:产生一个集合里面都是整数
public List getNumList(int num, Supplier sup){
List list = new ArrayList<>();
for (int i=0; i:函数型接口
@Test
public void test3(){
String s1 = strHandle("\t\t\t 你好,中国! ", s -> s.trim());
System.out.println(s1);
String s2 = strHandle("abcdf", s -> s.toUpperCase());
System.out.println(s2);
}
//需求:用于处理字符串
public String strHandle(String str, Function fun){
return fun.apply(str);
}
//Predicate:断言型接口
@Test
public void test4(){
List list = Arrays.asList("hello","www","lambda","ok");
List resList = filterStr(list, s -> s.length() > 3);
resList.forEach(System.out::println);
}
//取出满足条件的字符串
public List filterStr(List list, Predicate pred){
List strList = new ArrayList<>();
for(String str : list){
if (pred.test(str)){
strList.add(str);
}
}
/* list.forEach(x-> {
if (pred.test(x)){
strList.add(x);
}
});
*/
return strList;
}
}
1. 方法引用:
主要有三种语法格式:
对象::实例方法名
类::静态方法名
类::实例方法名
注意:
(1)Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数式列表和返回值类型保持一致!
(2)Lambda 参数列表中第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用 ClassName::method
2. 构造器引用
格式:ClassName::new
注意:需要调用的构造器的参数列表要与函数式接口中抽象方法参数列表保持一致!
3. 数组引用
格式:Type::new
public class TestMethodRef {
//对象::实例方法名
@Test
public void test1(){
PrintStream ps = System.out;
//Lambda表达式
Consumer con = x -> ps.println(x);
PrintStream ps1 = System.out;
//对象名::实例方法名
Consumer con1 = ps1::println;
Consumer con2 = System.out::println;
con2.accept("abcd");
}
@Test
public void test2(){
Employe emp = new Employe("赵云", 20,8888.88);
//Lambda表达式
Supplier sup = ()-> emp.getName();
String s = sup.get();
System.out.println(s);
//对象名::实例方法名
Supplier sup2 = emp::getAge;
Integer s2 = sup2.get();
System.out.println(s2);
}
//类::静态方法名
@Test
public void test3(){
//Lambda表达式
Comparator com = (x,y) -> Integer.compare(x,y);
int r = com.compare(10, 5);
System.out.println(r);
//类::静态方法名
Comparator com2 = Integer::compare;
int r2 = com2.compare(5, 10);
System.out.println(r2);
}
//类::实例方法名
@Test
public void test4(){
//Lambda表达式
BiPredicate bp = (x, y) -> x.equals(y);
//方法引用(规则:第一个参数是实例方法的调用者,第二个参数是实例方法的参数)
BiPredicate bp2 = String::equals;
}
//构造器引用
@Test
public void test5(){
//Lambda 表达式
Supplier sup = ()-> new Employe();
//构造器引用
Supplier sup2 = Employe::new;
}
//数组引用
@Test
public void test6(){
//Lambda 表达式
Function fun = (x)-> new String[x];
String[] strs = fun.apply(10);
System.out.println(strs.length);
//数组引用
Function fun2 = String[]::new;
String[] strs2 = fun.apply(8);
System.out.println(strs2.length);
}
}
【提示】可以理解把引用理解为 Lambda 表达式的另外一种表现形式