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;
    }
}

posted @ 2016-05-28 13:39  fcat  阅读(1183)  评论(0编辑  收藏  举报