JAVA8的新特性

网上介绍java8新特性的概念已经很多了,我就不过多说了;

直接教你怎么使用:

一.配置环境:

1.在工作空间的build.gradle中配置
buildscript {
    repositories {
        .....
        // Java8 环境的搭建,所使用的配置

mavenCentral()
    }
    dependencies {

classpath 'com.android.tools.build:gradle:2.2.0'
        // Java8 环境的搭建,所使用的配置

classpath 'me.tatarka:gradle-retrolambda:3.3.1'

}
}
allprojects {
    repositories {
        .....
        // Java8 环境的搭建,所使用的配置

mavenCentral()
    }

}
2.在app/build.gradle中配置
// Java8 环境的搭建,所使用的配置
apply plugin: 'me.tatarka.retrolambda'
android {
    ....
// Java8 环境的搭建,所使用的配置
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
下面紧接说一下Lambda式的使用(其中一个特性)

概念:java1.8及以上版本才有的新特性.是一种新的语法

使用Lambda表达式要求:1.java为1.8及以上版本        2.替换省略的代码必须是接口,且接口内只有一个方法.

http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650822789&idx=1&sn=aabf8b95e233a6bb19466e58fb90f812&chksm=80b78c1bb7c0050da725cb947e0ae3a657e74dbae210bd3228eeaa1f7a990e466bc31b25c0d0&mpshare=1&scene=23&srcid=0503IEuy3RzY0ycsMHxwAy9l#rd

Android使用Lambda,要先搭建环境(注意资源在国外,要*):android studio 2.1及版本以上
https://github.com/evant/gradle-retrolambda

使用Lambda表达式,对传统的代码进行修改,分为调用系统的,调用自己的,无参,有参,多参等:
A.这段传统写法的代码,真正有用的是run方法,new Runnable()这件事,就显得好无意义.
newThread(
//匿名内部类,主要用到的就是run方法
newRunnable() {
@Override
public voidrun() {
    Log.d("PY","使用系统原生的代码");
}
}) {
}.start();
//A.将上面的代码替换成Lambda表达式(Runnable()变成灰色)
//A.实际就是把没有什么作用的格式用 "()->" 替换,只保留有作用的核心代码.
newThread(() -> Log.d("PY", "使用系统原生的代码")) {
}.start();


1.自定义一个类,定义一个方法,接收一个接口,执行里面的方法

class MyButton {
public void setMyListener(MyListener myListener) {
    //接口对象调用接口唯一的一个抽象方法,如果没有调用参数就是灰色的

    myListener.onStateChanged();
}

}


1.定义一个接口,内部有且只能有一个抽象方法

interface MyListener {

//自定义一个接口,无参

void onStateChanged();

}

   使用我们自定义的格式换成Lambda表达式,接口方法无参
MyButton myButton = newMyButton();
myButton.setMyListener(newMyListener() {
@Override
public voidonStateChanged() {
    Log.d("PY","使用自己定义的代码");
}
});
//B.使用Lambda表达式,() ->代表了上面的new MyListener() {void onStateChanged()...的代码
myButton.setMyListener(() -> Log.d("PY", "使用自己定义的代码"));



2.自定义一个类,定义一个方法,接收一个接口,执行里面的方法

class MyButton {

String s;

public MyButton(String s) {

    this.s = s;

}
public void setMyListener(MyListener myListener) {
    myListener.onStateChanged(s);
}

}

2.定义一个接口,内部有且只能有一个抽象方法
interfaceMyListener {
//自定义一个接口,有参
void onStateChanged(String s);
}

    使用我们自定义的格式换成Lambda表达式,接口方法有参
MyButton myButton = new MyButton("岩");
myButton.setMyListener(new MyListener() {
@Override
public void onStateChanged(String s) {
Log.d("PY",s+"使用自己定义的代码");
   }
});
//B.使用Lambda表达式,第一种最常见,下面两种虽然更简化,但阅读性不好,一般我们不用,了解即可
myButton.setMyListener((String s)->Log.d("PY", s+"使用自己定义的代码"));
myButton.setMyListener((s)->Log.d("PY", s+"使用自己定义的代码"));
//这种写法,只能是接口方法的参数是一个,如果有多个的话,就不可以了
myButton.setMyListener(s ->Log.d("PY", s+"使用自己定义的代码"));


3.自定义一个类,定义一个方法,接收一个接口,执行里面的方法

class MyButton {

String s;

int i;

public MyButton(String s, int i) {

this.s = s;

this.i = i;

}
public void setMyListener(MyListener myListener) {
    //接口对象调用接口唯一的一个抽象方法
    myListener.onStateChanged(s,i);
}

}

3.定义一个接口,内部有且只能有一个抽象方法
interfaceMyListener {
//自定义一个接口,有多个参数
void onStateChanged(s,i);
}

用我们自定义的格式换成Lambda表达式,接口方法有多个参数
MyButton myButton =new MyButton("", 9);
myButton.setMyListener(newMyListener() {
@Override
public voidonStateChanged(String s,int i) {
    System.out.println(s + ""+i+"个老婆");
}
});
//B.使用Lambda表达式,注意:这里不是一行代码,而是多行,那么就要加{}
myButton.setMyListener((String s, int i) -> {
    System.out.println("岩富可敌国,所以有众多的追求者"); 
    System.out.println(s + ""+i+"个老婆"); }
);


4.自定义一个类,定义一个方法,接收一个接口,执行里面的方法

class MyButton {

String s;

int i;

public MyButton(String s, int i) {

this.s = s;

this.i = i;

}
public void setMyListener(MyListener myListener) {
    //接口对象调用接口唯一的一个抽象方法
    myListener.onStateChanged(s,i);
}

}

4.定义一个接口,内部有且只能有一个抽象方法
interface MyListener {
//自定义一个接口,有多个参数
boolean onStateChanged(s,i);
}

    使用我们自定义的格式换成Lambda表达式,接口方法有多个参数且还有返回值
MyButton myButton = new MyButton("", 9);

myButton.setMyListener(new MyListener() {

@Override

public boolean onStateChanged(String s, int i) {

System.out.println(s + ""+i+"个老婆");
        return false;
    }
});
//B.使用Lambda表达式    注意:这里就有了个return

myButton.setMyListener((String s, int i)->{
        System.out.println(s + "有"+i+"个老婆");
        return false;
    }
);

* 注意:这里自定义的接口,若没用接口对象调用,那么即便覆写了其方法,也不会执行,没有效果
http://blog.csdn.net/whatfizzer/article/details/46992149

使用前提:符合Lambda表达式,首先要是Lambda,
Lambda方法引用:一般我们不会去写,但是第三方库会用,看懂即可.非重点
提示:参数和返回值必须和接口的唯一抽象方法保持一致
/**
* F.使用Lambda静态引用方法
*/
private voidLambdaStaticMethod() {
MyButton myButton =new MyButton("",9);
myButton.setMyListener(newMyListener() {
@Override
public booleanonStateChanged(String s, inti) {
System.out.println(s +""+i+"个老婆");
return false;
}
    });
//使用Lambda表达式的静态方法引用,
myButton.setMyListener(MainActivity :: ycf);
}
/**
* Lambda方法引用:一般我们不会去写,但是第三方库会用,看懂即可.非重点
*提示:参数和返回值必须和接口的唯一抽象方法保持一致
*/
public static boolean ycf(String s, int i){
System.out.println("我是Lambda的静态方法引用");
return false;
}

静态方法引用格式:    类名 :: 方法名        例子ClassName :: MethodName
实例方法引用:        类对象 :: 方法名      例子instanceReference :: MethodName
类型方法引用:        类名 :: 方法名        例子ClassName :: MethodName
构造方法引用:Class :: new
二·Stream:

Stream是高级迭代器,以流的方式使用集合,数组以及其他数据结构,可以对数据进行各种运算(转换,过滤等)

注意:Android中Stream只能在单元测试里运行

使用Stream的基本步骤:创建Stream ; 转换Stream , 每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换);对Stream进行聚合操作,获取想要的结果

学习Stream的作用:
第一:一般情况你的简历:扎实的Java基础与面向对象思想,掌握Java8的新特性.
第二:rxJava又叫响应式编程 : 观察者模式 ,Lambda表达式, 使用Stream特性操作集合,进行异步加载

使用Stream过滤集合数据的步骤:
1.将集合转换为Stream流
2.对Stream进行数据筛选
3.输出筛选出来的数据

@TargetApi(Build.VERSION_CODES.N)
public static voidstreamFilter() {
//创建集合对象,塞入数据
List<Integer> integers = Arrays.asList(1,2,3,4,5);
//通过for循环,对集合的数据进行操作
for(intx = 0; x < integers.size(); x++) {
//需求,只要集合中的偶数,传统的做法就比较麻烦了
// System.out.println(integers.get(x));
}

//使用java1.8的新特性Stream,把数据源变成流,报错,按住alt+回车,选第二个.
java.util.stream.Stream<Integer> stream = integers.stream();
//只要集合中的偶数,内部有接口,返回值还是流
stream.filter(newPredicate<Integer>() {
@Override
public booleantest(Integer integer) {
//参数integer就是不断的代表集合中的一个数据,对数据进行筛选获取,true就代表了这个数据被选中
//对数除以2,余数是否为0;
returninteger % 2== 0;
}
})
//forEachfor循环一样,将流数据转化成对应集合类型数据进行输出,只不过输出的数据是集合中符合条件的数据
.forEach(newConsumer<Integer>() {
@Override
public voidaccept(Integer integer) {
System.out.println(integer);
}
});

//使用lambada表达式,对上面的代码进行优化,这里的最终运行,我就在测试类调用
/* integers.stream()
.filter((Integer integer) -> integer % 2 == 0)
.forEach((Integer integer) -> {
System.out.println("打印出来的数" + integer);
});*/
}

使用Stream转换集合数据,把原来集合中的数据类型,转换为新的数据类型:
1.将集合数据转换为Stream流
2.对Stream进行数据转换
3.输出筛选出来的数据

@TargetApi(Build.VERSION_CODES.N)
public static voidstreamMap() {
//创建集合对象,塞入数据
List<Integer> integers = Arrays.asList(1,2,3,4,5);
integers.stream()
//转换数据,参数 1.原有的参数类型对象 2.要转换的参数类型对象
.map(newFunction<Integer, String>() {
@Override
publicString apply(Integer integer) {
    returninteger.toString();
}
})
.forEach(newConsumer<String>() {
@Override
public voidaccept(String s) {
    System.out.println(s);
}
});
}
JAVA8的新特性