JDK1.8新特性
-
javac -source 1.7 -target 1.8 T.java 表示源文件版本为1.7,编译成的字节码使用1.8
-
lambda表达式,即由用户来提供行为的具体实现.
/**
* @author Sunset
* Created on 2016/05/15.
*/
public class T {
public static void main(String[] args) {
/**
* lambda语法,提供的是相应函数式接口的目标方法实现,并根据该实现创建一个接口的对象。
* 关于该目标方法的具体参数值,lambda表达式并不提供!!!!
* lambda表达式的标准写法为 (arg1,arg2) -> {statements;}
* 对于只有一个参数可以写为 arg -> {statements}
* 对于只有一条返回语句的实现可以写为 arg -> arg + "sss",其自动加return
*/
act(new Person("love"),p -> System.out.println(p.getName()));
// ClassName::method方法引用。
// 可以看做lambda表达式的一个特殊用法,该语法在stream的map、groupingBy等方法中特别有用。
// 其等价于classInstance -> classInstance.method()或
// classInstance -> {classInstance.method();}
// classInstance为ClassName类型的对应参数,并根据目标函数是否有返回值决定不同的调用方式。
// 以下等价于act(new Person("fff"),p -> p.getName());
act(new Person("fff"),Person::getName);
}
public static void act(Person p,MyLambda ml){
ml.sayHello();
ml.doSomthing(p);
ml.sayGoodBye();
}
}
/**
* 支持函数式接口的接口可以使用lambda表达式
*/
@FunctionalInterface
interface MyLambda{
//必须刚好提供一个目标方法(无default),lambda表达式将实际传入该方法,并创建对象
void doSomthing(Person s);
default void sayHello(){
System.out.println("hello");
}
default void sayGoodBye(){
System.out.println("GoodBye");
}
}
class Person{
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Person setName(String name) {
this.name = name;
return this;
}
}
- Stream类,它提供了类似于python中generator的概念,即只保存算法的一个类。是一个高版本的iterator。
//优势,可以提供自动并行化处理,可以产生无限元素。
/**
*可以由以下几种方式产生
*Collection.stream()
*静态方法LongStream.of(1,2,3,4);
*自定义
**/
/**
*流操作分为两种类型:
*Intermediate:一个流后面可一个跟多个Intermediate操作,其作用是打开流,对其数据进行某种程度的映射,并返回一个新流。
*该类操作都是lazy的,只有在terminal方法触发后,才开始遍历元素,也就是仅仅调用该类方法只是将操作放到stream的操作序
*列中,等到调用terminal时再对每一个元素调用执行。该类操作有,
*map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
*terminal,将流中的每一个元素读出,并操作,一个流最多只能有一个terminal操作,且必须为最后一个操作。
*该类操作有forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、
*noneMatch、 findFirst、 findAny、 iterator
**/
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Sunset
* Created on 2016/05/15.
*/
public class T {
public static void main(String[] args) {
/**
* -*- Intermiate方法 -*-
*filter过滤,接收一个Predicate
* map将每一个元素进行 1<->1 映射并返回新元素(可以返回不同的类型),接收一个Function
* flatmap,将一个元素进行1 -> *映射,多端结果用一个Stream保存
* peek获得每一个元素,不能改变元素,接收一个Consumer
* distinct去除重复元素
*
* limit(n)表示取前n個元素,skip(n)表示跳過前n個元素,這將#導致该操作前面#
* Intermediate操作所對應的元素數量減少。除非前面有sorted操作(不知道排序后的顺序,无法应用short-cut)
* eg:len(s) == 10,s.peek().sorted().peek().limit(5),则第一个peek以及sorted处理的元素个数为10,
* 第二个peek处理的元素个数为5
*
* -*- Terminal方法 -*-
* collect方法将其作为了个Collection返回
*
* reduce(start,Function),使用start作为初始种子,两两进行reduce操作
* min,max,sum,findFirst,findAny,count,forEach,forEachOrdered
* findFirst/findAny也是一个short-cut操作,可能skip后面的元素
*
* 以下三个Match方法并不一定遍历所有元素,只要足够返回条件,则skip剩余元素。
* allMatch,判断是否全部符合
* anyMatch,有一个符合即可
* noneMatch,无符合
*
**/
Stream<String> stringStream = Stream.of("a", "b", "c", "a");
//此时由于都是Intermediate操作所以并不执行,所以peek操作不会打印
Stream<Integer> ins = stringStream.filter(x -> x != null).map(x -> x.hashCode()).distinct().peek(x -> System.out.println(x));
//此时调用了一个terminal方法,所以前面的Intermediate操作也被执行,所以peek打印hash值
//anyMatch有skip功能,所以上面的peek不是打印全部元素。
ins.anyMatch(x -> x == 98);
/**
* 自定义生成流,先实现Supplier接口,然后调用Stream.generate()来生成
* 以下生成一个等差数列
*/
Stream<Integer> dc = Stream.generate(new Supplier<Integer>() {
int x = 0;
@Override
public Integer get() {
x += 3;
return x;
}
});
//不是一个并行流返回false
System.out.println(dc.isParallel());
//count用于终结触发前面的中间方法。
dc.limit(4).peek(x -> System.out.println(x)).count();
/**
* Collectors提供了很多有用的reduction方法,可以将stream通过collect转成集合
* Person::getAge为lambda表达式的特殊用法,等价于 person -> person.getAge()
*/
Map<Integer, List<Person>> personGroups = Stream.generate(new PersonSupplier()).
limit(100).
collect(Collectors.groupingBy(Person::getAge));
System.out.println(personGroups);
System.out.println();
}
}
class Person{
private int age;
private String name;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public Person setName(String name) {
this.name = name;
return this;
}
public Person setAge(int age) {
this.age = age;
return this;
}
}
class PersonSupplier implements Supplier<Person>{
private Random random = new Random();
@Override
public Person get() {
Person p = new Person();
p.setAge(random.nextInt(20));
p.setName("sss");
return p;
}
}