JDK8新特性-流Stream,Lambda表达式以及Comparator和Comparable使用

Lambda Jdk8

Lambda 是一个匿名函数,只关注参数列表和方法体,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)

类型推断:省略参数类型

与内部类比较

内部类this关键字指向内部类本身,Lambda中this指向lambda所处在的类

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

表达式

引入了->新操作符:参数表加操作体

(Parameters)->{expressions}

方法引用

类名 :: 方法名

功能接口(使用要求)

使用@FunctionalInterface注解

接口中的抽象方法只能是一个(函数式接口)

Predicate

java.util.function.Predicate函数式接口,向API方法添加逻辑,非常适合做过滤器

        List<String> names=Arrays.asList("dx","wdt","zfb","wuguangyao","nihaoshiw"));
        Predicate<String> filter1 = str->str.length()>5;
        Predicate<String> filter2 = str->str.endsWith("yao");
       // filter(names,(n)->((String)n).startsWith("d"));
        filter(names,filter2);
        names.stream().filter(filter1.and(filter2))
                .forEach(System.out::println);
    }

    public static void filter(List<String> list, Predicate condition){
        for(String str:list){
            if(condition.test(str)){
                System.out.println(str);
            }
        }
    }

Runnable

Runnable t = ()-> System.out.println("hello");
        t.run();

s

Collections

根接口

sort

implements Comparable

实体类实现Comparable接口

public class Student implements Comparable<Student> {
~~~~
@Override
    public int compareTo(Student o) {
        return stuId.compareTo(o.getStuId());
    }

Collections.sort(List<?>,new Comparator())

创建一个比较器实现Comparator接口

Collections.sort(list, new Comparator<StudentNoSort>() {
            @Override
            public int compare(StudentNoSort o1, StudentNoSort o2) {
                return o1.getStuId().compareTo(o2.getStuId());
            }
        });

Stream

使用Jdk8 Stream更加简单

List<StudentNoSort> streamList = list.stream()
                .filter(w -> w.getClass()==StudentNoSort.class)
                .sorted(((o1, o2) -> o1.getStuId().compareTo(o2.getStuId())))
                .collect(Collectors.toList());

Stream

Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

Stream构成

获取一个数据源(source)→ 数据转换→执行操作(返回新的Stream对象),这就允许对其操作可以像链条一样排列,变成一个管道

1561548534995

Stream Source

集合,数组,I/O channel, 产生器generator 等

Stream Operation

Intermediate

一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。

collect

创建一个List

filter

过滤器:集合进行过滤操作

distinct

集合元素去重

map

对函数进行操作

reduce

组合元素

forEach

遍历元素

limit

限定流中数据的数量

skip

接受参数N跳过前N个元素

sorted

排序 使用Comparator接口

march,allMatch,noneMatch,anyMatch

符合元素传入predicate,返回boolean

还有以下

mapToInt (转换为int), summaryStatistics(int型变量统计) ,sum(int型求和)

Terminal

一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。

匹配

findAny() .orElse(null); 找到返回任意一个找到的,否则返回null

构造Stream

Collections

Collections
List<String> list = Arrays.asList(strArray);
stream = list.stream();

example:

List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 12, 1, 1, 2, 3, 2, 432, 4, 32, 54, 3, 3));
        int sum = list.stream().map(x -> x * x)
                .reduce((x, y) -> x + y)
                .get();

遍历文件(nio+lambda)

Path start = FileSystems.getDefault().getPath("/home/dzou/报告/模电");
        Files.walk(start)
                .filter(path -> path.toFile().isFile())
                .filter(path -> path.toString().endsWith(".jpg"))
                .forEach(System.out::println);

时间复杂度

Stream 里有个操作函数的集合,每次转换操作就是把转换函数放入这个集合中,在 Terminal 操作的时候循环 Stream 对应的集合,然后对每个元素执行所有的函数

并行parallelStream

我们看这个代码,输出不是顺序的

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        numbers.parallelStream()
                .forEach(out::println);

底层使用ForkJoinPool,相比于ThreadPoolExecutor,可以让线程创建新的任务,并挂起当前任务,此时线程可以在队列中选择子任务执行

  • 本文作者: dzou | 微信:17856530567
  • 本文链接: http://www.dzou.top/post/8184a8fd.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
  • 并保留本声明和上方二维码。感谢您的阅读和支持!