JDK1.8新特性
来源:互联网 发布:台湾文献数据库 编辑:程序博客网 时间:2024/05/21 06:32
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表达式 */@FunctionalInterfaceinterface MyLambda{ //必须刚好提供一个目标方法(无default),lambda表达式将实际传入该方法,并创建对象,使用@FunctionalInterface进行约束. 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; }}//再看reduce系列方法1. Optional reduce(BinaryOperator<T> bo);该方法在stream元素为空时,返回Optional.EMPTY,在元素个数为一时直接将该元素添加到Optional中,否则进行reduce操作,初始选择头两个元素,然后以两个元素的reduce结果作为下一次reduce的第一个元素,进行下一次reduce操作。实际流程类似下方: boolean foundAny = false; T result = null; for (T element : this stream) { if (!foundAny) { foundAny = true; result = element; } else result = accumulator.apply(result, element); } return foundAny ? Optional.of(result) : Optional.empty();2. T reduce(T identity,BinaryOperator<T> bo);该方法可以直接返回T,而不是一个Optional,因为提供了第一个元素identity,所以不会返回空结果,其余规则与一相同。3.<R, A> R collect(Collector<? super T, A, R> collector);可以注意到一二两个reduce操作,其要求每次reduce操作的结果(中间结果)以及最终返回结果都与T一致,所以系统提供一个灵活的collect方法。其中R表示最终返回结果,A表示中间结果。 Collector接口的方法如下 //该方法返回一个Supplier对象(可用lambda),该对象用于提供一个中间结果,会用于实际reduce Supplier<A> supplier() //用于执行实际的reduce操作 BiConsumer<A, T> accumulator() //将中间结果转换为返回结果类型 Function<A, R> finisher() //用于标识流类型,Characteristics.CONCURRENT/UNORDERED有且只有一个在集合中。 Set<Characteristics> characteristics() //暂时忽略 BinaryOperator<T> combiner() collect的实际工作流程如下 1)调用collector.supplier().get()返回一个中间结果类型对象a。 2)对每个元素e调用collector.accumulator.accept(a,e)进行reduce操作,该调用每次都是用第一步产生的a,返回值是void,这意味着a是一个可变对象reduce操作才有意义。 3)调用collector.finisher().apply(a)返回真正的结果对象。4.Collectors提供了许多方法可以快速生成Collector对象。总结如下:groupingBypartitionBytoListtoMaptoSettoConcurrentMapaverageing*summing*summarizing*//最终返回统计对象,可以获得avg/sum/min等数据joining//连接元素一个小demo,计算九个字符串的hashcode加和/** * @author Sunset * Created on 2016/07/29. */public class X { public static void main(String[] args) { List<List<String>> lists = new ArrayList<>(); List<String> l1 = new ArrayList<>(); l1.add("l1_1"); l1.add("l1_2"); l1.add("l1_3"); List<String> l2 = new ArrayList<>(); l1.add("l2_1"); l1.add("l2_2"); l1.add("l2_3"); List<String> l3 = new ArrayList<>(); l1.add("l3_1"); l1.add("l3_2"); l1.add("l3_3"); lists.add(l1); lists.add(l2); lists.add(l3); Integer i = lists.stream().flatMap(Collection::stream).collect(new Collector<String, IntegerHoler, Integer>() { @Override public Supplier<IntegerHoler> supplier() { return IntegerHoler::new; } @Override public BiConsumer<IntegerHoler, String> accumulator() { return (ih,s) -> ih.setI(ih.getI()+s.hashCode()); } @Override public BinaryOperator<IntegerHoler> combiner() { return null; } @Override public Function<IntegerHoler, Integer> finisher() { return IntegerHoler::getI; } @Override public Set<Characteristics> characteristics() { Set<Characteristics> ss = new HashSet<Characteristics>(); ss.add(Characteristics.CONCURRENT); return ss; } }); System.out.println(i); }}class IntegerHoler{ private Integer i = new Integer(0); public Integer getI() { return i; } public IntegerHoler setI(Integer i) { this.i = i; return this; }
1 0
- jdk1.8 新特性
- jdk1.8新特性
- jdk1.8新特性
- jdk1.8新特性
- JDK1.8-新特性
- JDK1.8新特性
- JDK1.8新特性
- jdk1.8新特性
- JDK1.8新特性
- jdk1.8新特性
- JDK1.8新特性
- JDK1.8新特性
- JDK1.8新特性
- jdk1.8新特性
- JDK1.8新特性
- JDK1.7和JDK1.8新特性
- JDK1.5-JDK1.8的新特性
- Java JDK1.8新特性
- web服务器集群(多台web服务器)session同步、共享的3种解决方法
- shell简单编程
- java泛型
- Subsets
- JavaScript 高级课程之缓冲+多个DIV运动框架实现 + 透明度
- JDK1.8新特性
- 求1!+2!+3!+......+n!
- 农村土地确权之调查公示 —— 地块分布图制作说明
- Clojure小教程(更新中)
- 捕捉HTTP数据,解析Request header
- 32位 64位 各类型字节数
- Sass安装
- mysql MVCC之InnoDB实现
- PowerDesigner连接数据库附PowerDesigner15.1汉化破解版