Java8——Lambda基础语法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rubulai/article/details/88737454
Lambda操作符

 Lambda操作符(->)将Lambda表达式拆分成两部分:
  左侧:Lambda表达式的参数列表,对应函数式接口的方法的参数列表
  右侧:表达式所需执行的代码逻辑,即Lambda体,对应接口方法的实现
 也就是说Lambda表达式需要函数式接口的支持,即只有一个抽象方法的接口,这种类型的接口可以使用@FunctionalInterface注解

语法格式

 1、无参数,无返回值:() -> 逻辑代码

public void test() {
	//匿名内部类的方式
	Runnable r = new Runnable() {
		@Override
		public void run() {
			System.out.println("Hello world!");
		}
	};
	r.run();

	//Lambda表达式的方式
	Runnable rl = () -> System.out.println("Hello Lambda!");
	rl.run();
}

 Runnable接口如下:

@FunctionalInterface
public interface Runnable {
	void run();
}

  由此可见()->System.out.println(“Hello Lambda!”);相当于对Runnable 接口中的run()方法的实现,因此我们在调用rl的run()方法时即可看到相应的效果。
注意:JDK1.8以前在匿名内部类中如果使用了同级别的类变量,则该变量必须声明为final,JDK1.8之后则不需要显示声明为final,但是一旦变量在匿名内部类中的方法使用则自动变成final类型,在Lambda表达式中也是如此。

public class TestLambda {
	
	int num = 0;//无需显示声明为final,但是一旦在匿名内部类或者Lambda表达式中使用该变量则该变量会被转化为final的

	@Test
	public void test() {
		//匿名内部类的方式
		Runnable r = new Runnable() {
			@Override
			public void run() {
				System.out.println("Hello world!" + num);
			}
		};
		r.run();

		//Lambda表达式的方式
		Runnable rl = () -> System.out.println("Hello Lambda!" + num);
		rl.run();
	}
}

 2、有一个参数,无返回值:(x) -> 逻辑代码,此时小括号可以省略
  函数式接口:

@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

  Lambda表达式实现和调用:

public void test1(){
	Consumer<String> con = (x) -> System.out.println(x);
	con.accept("Hello Lambda!");
}

public void test2(){
	//省略小括号
	Consumer<String> con = x -> System.out.println(x);
	con.accept("Hello Lambda!");
}

 3、有多个参数,有返回值,且Lambda体有多个语句:使用大括号{}将方法体括起来,并使用return返回结果
  函数式接口:

@FunctionalInterface
public interface Comparator<T> {
    
    int compare(T o1, T o2);
	
	//....
}

  Lambda实现和调用:

public void test2() {
	Comparator<Integer> com = (x, y) -> {
		System.out.println("比较大小...");
		return Integer.compare(x, y);
	};
	System.out.println(com.compare(1, 2));
}

 当有多个参数,有返回值,但Lambda体有一条语句时,大括号和return关键字可省略:

public void test2() {
	Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
	System.out.println(com.compare(1, 2));
}

说明:以上通过Lambda表达式书写参数列表时我们都没有写参数的数据类型,这是因为JVM编译器可以通过上下文推断出数据类型,即类型推断。但有时JVM是无法推断出数据类型的,这时就需要我们指定数据类型,且一旦指定就需要指定全部形参的数据类型(按说这种情况是不会出现的,因为函数式接口中只会有一个抽象方法)。

示例

 函数式接口声明:

@FunctionalInterface
public interface MyCal<T> {
	Integer cal(T t1, T t2);
}

 Lambda实现和调用:

public class TestLambda {

	@Test
	public void test3() {
		Integer myCal = myCal(100, 200, (x, y) -> x * y);
		System.out.println(myCal);

	}

	private Integer myCal(Integer x, Integer y, MyCal<Integer> cal) {
		return cal.cal(x, y);
	}
}
练习

 1、对员工先根据年龄排序,年龄相同则根据姓名排序

public class LambdaExp {

	List<Employee> employees = new ArrayList<Employee>(Arrays.asList(
			new Employee("zhangsan", 24, 5050.00),
			new Employee("lisi", 28, 6666.00), 
			new Employee("wangwu", 32, 3333.00), 
			new Employee("xueliu", 43, 2222.00),
			new Employee("tianqi", 28, 7777.00), 
			new Employee("maer", 36, 8888.00)
		));

	@Test
	public void test() {
		Collections.sort(employees, (e1, e2) -> {
			if (e1.getAge() == e2.getAge())
				return e1.getName().compareTo(e2.getName());
			else
				return Integer.compare(e1.getAge(), e2.getAge());
		});
		for (Employee employee : employees) {
			System.out.println(employee);
		}
	}
}

 2、对字符串进行自定义操作
  定义函数式接口

@FunctionalInterface
public interface StringHandler {
	String handler(String str);
}

  自定义处理字符串的方法:将接口作为方法的入参

public String strHandler(String str, StringHandler handler) {
	return handler.handler(str);
}

  调用时实现处理逻辑

public void test1() {
	String strHandler = strHandler("abcdef", x -> x.toUpperCase());
	System.out.println(strHandler);

	String strHandler2 = strHandler("我爱Lambda", x -> x.substring(2));
	System.out.println(strHandler2);
}

 3、定义泛型接口对数据进行操作
  定义函数式接口

@FunctionalInterface
public interface GenericInterface<T, R> {
	R cal(T t1, T t2);
}

  自定义处理泛型数据的方法

private Double myCal(Long l1, Long l2, GenericInterface<Long, Double> gi) {
	return gi.cal(l1, l2);
}

  实现和调用

public void test2() {
	Double myCal = myCal(100L, 30L, (x, y) -> (double) (x / y));
	System.out.println(myCal);
}

猜你喜欢

转载自blog.csdn.net/rubulai/article/details/88737454