关闭

Java8のLambda学习

265人阅读 评论(0) 收藏 举报
分类:
转载自:http://www.jb51.net/article/48304.htm
              http://www.oschina.net/translate/everything-about-java-8

Lambda表达式

       使用Java8之前的语法,如何实现比较器:
List<Integer> list = Arrays.asList(7, 4, 1, 2);
Collections.sort(list, new Comparator<Integer>() {
      @Override
      public int compare(Integer a, Integer b) {
           return a > b ? 1 : (a == b) ? 0 : -1;
      }
});
System.out.println(list);// [1, 2, 4, 7]
       在Java 8 中就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式:
Collections.sort(list, (Integer a, Integer b) -> {
      return a > b ? 1 : (a == b) ? 0 : -1;
});
       代码变得更段且更具有可读性,但是实际上还可以写得更短:
Collections.sort(list, (Integer a, Integer b) -> a > b ? 1 : (a == b) ? 0 : -1);
       对于函数体只有一行代码的,可以去掉大括号{}以及return关键字,但是还可以写得更短点:
Collections.sort(list, (a, b) -> a > b ? 1 : (a == b) ? 0 : -1);
       Java编译器可以自动推导出参数类型,所以可以不用再写一次类型。
       当把经典风格java语法转变为Lambda表达式语法时,主要关注接口方法的参数和功能逻辑。

       另外一个例子,如果打算写一个方法,此方法接收一个Lambda表达式作为参数,那么该怎么写?首先把方法参数声明成函数接口,然后才能传递Lambda表达式进来,如下所示:
interface Action {
    void doThing(String param);
}
public void func(Action actor) {
    actor.doThing("Hello World!");
}
       如果想要调用func()方法,那么通常地做法,给func方法传递一个Action的匿名实现类。如下所示:
new LambdaTest().func(new Action() {
      @Override
      public void doThing(String param) {
           System.out.println("Hi! " + param);
      }
});
       但是现在有函数接口做参数类型,所以可以用下面的方式调用func ():
new LambdaTest().func((String parm) -> {
      System.out.println("Hi! " + parm);
});
       甚至可以更简单:
new LambdaTest().func(parm -> System.out.println("Hi! " + parm));

接口的默认方法(default)

       Java 8允许给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,示例如下:
public class Test {
	public static void main(String[] args) {
		Formula formula = new Formula() {
			@Override
			public double calculate(int a) {
				return sqrt(a * 100);
			}
		};
		System.out.println(formula.calculate(100)); // 100.0
		System.out.println(formula.sqrt(16)); // 4.0
	}
}

interface Formula {
	double calculate(int a);

	default double sqrt(int a) {
		return Math.sqrt(a);
	}
}

函数式接口

       Lambda表达式是如何在java的类型系统中表示的呢?每一个lambda表达式都对应一个类型,通常是接口类型。而“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。因为默认方法不算抽象方法,所以也可以给你的函数式接口添加默认方法。
       可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保接口一定达到这个要求,只需要给接口添加 @FunctionalInterface 注解,编译器如果发现标注了这个注解的接口有多于一个抽象方法的时候会报错的。
@FunctionalInterface
interface Converter<F, T> {
	T convert(F from);
}
Converter<String, Integer> converter = (aa) -> Integer.valueOf(aa);
Integer converted = converter.convert("123");
System.out.println(converted); // 123
需要注意如果@FunctionalInterface如果没有指定,上面的代码也是对的。

       JDK8中新增了一个包,java.util.function,这个包里有一些专门给新增的API使用的函数接口。
       下面列出几个java.util.function中定义的接口:
    public interface Consumer<T> : void accept(T t);//在T上执行一个操作,无返回结果
    public interface Supplier<T> : T get();//无输入参数,返回T的实例
    public interface Predicate<T> : boolean test(T t);// 输入参数为T的实例,返回boolean值
    public interface Function<T, R> : R apply(T t);// 输入参数为T的实例,返回R的实例


方法引用:                       

静态方法引用:      String::valueOf
非静态方法引用:  Object::toString
继承的函数引用:   x::toString
构造函数引用:     ArrayList::new

方法引用                  等价的lambda表达式
String::valueOf         x -> String.valueOf(x)
Object::toString        x -> x.toString()
x::toString                () -> x.toString()
ArrayList::new         () -> new ArrayList<>()







0
0
查看评论

Java8学习(1) - lambda体验区

Oracle在Java8 中开始正式引入lambda表达式,虽然迟来了一些,但是作为Java开发者我们还是很兴奋的。在进入正式的学习前,我们现在体验区体验一下lambda的魅力所在。
  • zhongwcool
  • zhongwcool
  • 2015-02-12 11:52
  • 1277

java8 Lambda表达式的学习与测试

java lambda表达式
  • BabyGoodMorning
  • BabyGoodMorning
  • 2016-09-14 00:31
  • 869

java8学习 -- lambda表达式

参考文章 http://f.dataguru.cn/thread-656507-1-2.html 字符串排序: public class Test2 { /** * 对字符串排序 */ public void strSortForList(List ...
  • f1024042400
  • f1024042400
  • 2016-07-11 16:10
  • 169

Java8新特性之lambda

Java8中最重要的特性之一就是引入了lambda表达式。这能够使你的代码更加简练,并允许你将行为传递到各处。一段时间以来,Java因为自身的冗长和缺少函数式编程的能力而受到批评。随着函数式编程变得越来越流行和有价值,Java也在努力接受函数式编程。否则,Java将会变得没有价值。
  • u013291394
  • u013291394
  • 2016-09-16 21:46
  • 3148

Java8之——Lambda表达式入门

转载自:http://blog.csdn.net/renfufei/article/details/24600507/ 原文链接: Start Using Java Lambda Expressions 下载示例程序 Examples.zip 。 原文日期: 2014年4月1...
  • l1028386804
  • l1028386804
  • 2016-09-22 04:48
  • 1405

欺骗异常 – Java 8 Lambdas

抛开检查异常和运行时异常的宗教争论,有很多次那些处理检查异常的例子的可怜构造类库就能让你发疯。 考虑下面你可能想要写的一小段代码: ``` public void createTempFileForKey(String key) { Map<String, File> tempF...
  • supercrsky
  • supercrsky
  • 2015-05-21 15:06
  • 2223

Java8 lambda使用总结-结合实例介绍

摘要: 1.Java8 新特性介绍 2.项目中应用 1.Java8 新特性介绍 原文链接 https://my.oschina.net/chenxiaobian/blog/704421 写java的同学对java8肯定知道 那么java8到底有哪些特性呢,总结如下: Lam...
  • QWERTY1994
  • QWERTY1994
  • 2017-06-03 10:33
  • 1294

java匿名内部类以及java8新增的lambda方法

说实话啊,本来以为自己的匿名内部类学的还可以,可是在学习hashSet方法中重写了comparable函数式接口时,居然被这个匿名内部类,弄得自己一头雾水,真是恼火啊,自己又重新看了一遍,对它有了一定的理解了。 那就通过一个小例子来演示一遍吧,首先你得了解内部类,言简意赅就是在类之内再定义一个类,不...
  • sinat_34231260
  • sinat_34231260
  • 2016-08-17 15:58
  • 1312

JAVA8 Lambda表达式完全解析

JAVA8 新特性 在学习JAVA8 Lambda之前,必须先了解一下JAVA8中与Lambda相关的新特性,不然对于一些概念会感到比较陌生。 1、 接口的默认方法和静态方法 Java 8允许我们给接口添加一个默认方法,用default修饰即可。默认方法可以重写,也可以不用重写。这就是...
  • maplejaw_
  • maplejaw_
  • 2016-05-08 22:13
  • 2897

JAVA8 匿名内部类和lambda表达式

一.匿名内部类   匿名内部类适合创建那种只需要一次使用的类,例如前面介绍命令模式时所需要的Command对象,匿名内部类的语法有点奇怪,创建匿名内部类时会立即创建一个该类的实例,这个类的定义立即消失,匿名内部类不能重复使用。 语法格式一般如下: new 实现接口() | 父类构造器 (实参列...
  • zhangjikuan
  • zhangjikuan
  • 2017-07-16 19:29
  • 595
    个人资料
    • 访问:301291次
    • 积分:5476
    • 等级:
    • 排名:第5834名
    • 原创:203篇
    • 转载:243篇
    • 译文:0篇
    • 评论:26条