目前Java 8的新特性Lambda 结合 RxJava 在一起使用可以简化大量的代码,下面简单介绍在AndroidStudio中配置Gradle使得支持Java 8。

Android 使用Java8 配置

添加插件retrolambda

在project层的build.gradle配置

buildscript {    repositories {        jcenter()        mavenCentral()    }    dependencies {        classpath 'com.android.tools.build:gradle:2.2.0'        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'        classpath 'me.tatarka:gradle-retrolambda:3.2.5' //添加插件retrolambda        // NOTE: Do not place your application dependencies here; they belong        // in the individual module build.gradle files    }}

配置android{}区块Jav//java版本8

compileOptions {    sourceCompatibility JavaVersion.VERSION_1_8    targetCompatibility JavaVersion.VERSION_1_8}

配置完成之后的build.gradle文件

buildscript {    repositories {        mavenCentral()    }    dependencies {        classpath 'me.tatarka:gradle-retrolambda:3.2.4' //for java 8 lamda    }}apply plugin: 'com.android.application'apply plugin: 'me.tatarka.retrolambda'android {    compileSdkVersion 23    buildToolsVersion "23.0.1"    defaultConfig {        applicationId "com.mrljdx.sample"        minSdkVersion 10        targetSdkVersion 23        versionCode 1        versionName "1.0"    }    //java版本8    compileOptions {        sourceCompatibility JavaVersion.VERSION_1_8        targetCompatibility JavaVersion.VERSION_1_8    }    .....//省略其他配置}dependencies {    compile fileTree(include: ['*.jar'], dir: 'libs')    testCompile 'junit:junit:4.12'    //java 8 配置    retrolambdaConfig 'net.orfjackal.retrolambda:retrolambda:+'}配置proguard.pro混淆文件## see https://github.com/evant/gradle-retrolambda for java 8-dontwarn java.lang.invoke.*

Lambda表达式

lambda表达式取代了匿名内部类,取消了模板,允许程序猿用函数式风格编写代码,使代码可读性更高,尽管刚开始你会看不懂,但是你应该尝试,毕竟这是新的东西,我已从中获益。

格式

基本格式是:() -> {}

有下面三种具体表达:

1.(params) -> expression
2.(params) -> statement
3.(params) -> {statement}

使用Java 8 lambda表达式进行事件处理

传统的点击事件,应用匿名内部类:

 Button button = new Button(mContext); button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(mContext, "button click", Toast.LENGTH_SHORT).show();            }        });    }

如果按照之前Studio配置好了的话会有提示:
Android 使用jdk1.8新特性之lambda表达式_第1张图片

使用lambda表达式之后是这样的

button.setOnClickListener(v -> Toast.makeText(mContext, "button click", Toast.LENGTH_SHORT).show());

一行代码就搞定了,清晰可见,把行为传到了函数里,这里注意v不可省略,是函数onClick的参数;

传统实现Runnable接口是这样的:

new Thread(new Runnable() {    @Override    public void run() {        Log.i("TAG", "haha");    }}).start();

使用lambda表达式之后是这样的:

new Thread(() -> {    Log.i("TAG", "haha");}).start();

使用lambda表达式对列表进行迭代

List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");for (String feature : features) {    System.out.println(feature);}// Java 8之后:List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");features.forEach(n -> System.out.println(n));// 使用Java 8的方法引用更方便,方法引用由::双冒号操作符标示,// 看起来像C++的作用域解析运算符features.forEach(System.out::println);输出结果:LambdasDefault MethodStream APIDate and Time API

使用lambda表达式和函数式接口Predicate

除了在语言层面支持函数式编程风格,Java 8也添加了一个包,叫做 java.util.function。它包含了很多类,用来支持Java的函数式编程。其中一个便是Predicate,使用 java.util.function.Predicate 函数式接口以及lambda表达式,可以向API方法添加逻辑,用更少的代码支持更多的动态行为。下面是Java 8 Predicate 的例子,展示了过滤集合数据的多种常用方法。Predicate接口非常适用于做过滤。

public static void main(args[]){    List languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");    System.out.println("Languages which starts with J :");    filter(languages, (str)->str.startsWith("J"));    System.out.println("Languages which ends with a ");    filter(languages, (str)->str.endsWith("a"));    System.out.println("Print all languages :");    filter(languages, (str)->true);    System.out.println("Print no language : ");    filter(languages, (str)->false);    System.out.println("Print language whose length greater than 4:");    filter(languages, (str)->str.length() > 4);}public static void filter(List names, Predicate condition) {    for(String name: names)  {        if(condition.test(name)) {            System.out.println(name + " ");        }    }}输出结果:Languages which starts with J :JavaLanguages which ends with aJavaScalaPrint all languages :JavaScalaC++HaskellLispPrint no language :Print language whose length greater than 4:ScalaHaskell// 更好的办法public static void filter(List names, Predicate condition) {    names.stream().filter((name) -> (condition.test(name))).forEach((name) -> {        System.out.println(name + " ");    });}

如何在lambda表达式中加入Predicate

上个例子说到,java.util.function.Predicate 允许将两个或更多的 Predicate 合成一个。它提供类似于逻辑操作符AND和OR的方法,名字叫做and()、or()和xor(),用于将传入 filter() 方法的条件合并起来。例如,要得到所有以J开始,长度为四个字母的语言,可以定义两个独立的 Predicate 示例分别表示每一个条件,然后用 Predicate.and() 方法将它们合并起来,如下所示:

// 甚至可以用and()、or()和xor()逻辑函数来合并Predicate,// 例如要找到所有以J开始,长度为四个字母的名字,你可以合并两个Predicate并传入Predicate startsWithJ = (n) -> n.startsWith("J");Predicate fourLetterLong = (n) -> n.length() == 4;names.stream()    .filter(startsWithJ.and(fourLetterLong))    .forEach((n) -> System.out.print("nName, which starts with 'J' and four letter long is : " + n));

…还有很多使用方法详细查看:Java8 lambda表达式10个示例

比较

既然lambda表达式即将正式取代Java代码中的匿名内部类,那么有必要对二者做一个比较分析。

第一个关键的不同点就是关键字 this。匿名类的 this 关键字指向匿名类,而lambda表达式的 this 关键字指向包围lambda表达式的类。

第二是编译方式。Java编译器将lambda表达式编译成类的私有方法。使用了Java 7的 invokedynamic 字节码指令来动态绑定这个方法。

参考:Android Studio 配置

jdk1.8新特性之lambda表达式及在Android Studio中的使用

Java8 lambda表达式10个示例

Java 8简明教程

更多相关文章

  1. Android 修改app图标和名称的方法
  2. 【Android】adapter has changed解决方法
  3. android中控件点击两次才响应onclick方法
  4. android彻底结束进程的两种方法
  5. android和html交互--动态注入方法
  6. Android方法数超出限定的问题(multiDex,jumboMode)
  7. Android原生方法和Web JS互相调用-两种写法
  8. android 访问网络不能在主线程中进行以及在线程中操作UI的解决方
  9. Android Studio——Android Studio更新升级方法

随机推荐

  1. Android(安卓)泛型使用
  2. Android之Input子系统事件分发流程
  3. Android(安卓)弹出菜单
  4. Android(安卓)Timer 更好方法
  5. android 播放视频
  6. Android电话拨号器实现方法
  7. Android(安卓)studio无法更新 提示网络连
  8. Android语音识别功能使用总结
  9. Session 'MainActivity': Error Launchin
  10. Android应用程序(activity)启动过程(二)