Java8新特性

java8已经出来很久了,以前看过,但平时用的还是很少,现在重新学习下,以后工作中也尽量去用新的功能,边学习边写文章记录下来加深理解

lambda表达式

还是看对列表进行排序

List<String> list = Arrays.asList("apple", "banana", "orange");
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return b.compareTo(a);
            }
        });
        System.out.println(list);

上面的代码在Java8里可以改写为

        Collections.sort(list, (String a, String b) -> {
            return b.compareTo(a);
        });
        System.out.println(list);

使用()->{}代替匿名函数部分,还可以更简短一些

Collections.sort(list, (String a, String b) -> b.compareTo(a));

还可以省略参数类型

Collections.sort(list, (a, b) -> b.compareTo(a));

函数式接口

Lambda表达式如何匹配Java的类型系统?每一个lambda表达式都能够通过一个特定的接口与一个给定的类型进行匹配。一个所谓的函数式接口必须要有且仅有一个抽象方法声明。每个与之对应的lambda表达式必须要与抽象的方法声明相匹配。由于默认方法不是抽象的,因此你可以在你的函数式接口里添加任意的默认方法。任意一个包含抽象方法的接口我们都可以用来做lambda表达式,为了让你的接口满足需求,你应该在接口上加上@FunctionalInterface注解。编译器会注意这个注解,如果你的接口中有第二个抽象方法,编译器会抛出异常。

@FunctionalInterface
public interface Convert<F,T>{
    T convert(F from);
}

Convert<String,Integer> convert = from -> Integer.valueOf(from);
Integer integer = convert.convert("123");
System.out.println(integer);

方法和构造函数引用

上面的方法还可以使用静态方法引用

Convert<String,Integer> convert = Integer::valueOf;
Integer integer = convert.convert("123");
System.out.println(integer);

Java 8 允许你通过::关键字获取方法或者构造函数的的引用
方法引用的标准形式是 类名::方法名(只需要写方法名,不需要括号)
引用静态方法 ContainingClass::staticMethodName
引用某个对象的实例方法 containingObject::instanceMethodName
引用某个类型的任意对象的实例方法 ContainingType::methodName
引用构造方法 ClassName::new

数据流

Stream是java8引入的一个重度使用lambda表达式的API。Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高阶抽象。直观意味着开发者在写代码时只需关注他们想要的结果是什么而无需关注实现结果的具体方式
数据过滤

     List<String> list = Arrays.asList("a1","a2","b1","c2","c1");

        Stream<String> stream = list.stream();

        stream = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("c");
            }
        });

        stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

引入lambda表达式改写如下

        List<String> list = Arrays.asList("a1","a2","b1","c2","c1");

        Stream<String> stream = list.stream();

        stream = stream.filter(s -> s.startsWith("c"));

        stream.forEach(System.out::println);

衔接操作

        stream
                .filter(s -> s.startsWith("c"))
                .map(String::toUpperCase)
                .sorted()
                .forEach(System.out::println);//输出C2 C1
        //mapToInt
        IntStream intStream = Stream.of("1", "2", "3").mapToInt(Integer::valueOf);
        intStream.forEach(value -> System.out.println(value + 1));
        //mapToLong
        LongStream longStream = Stream.of("1", "2", "3").mapToLong(Long::valueOf);
        longStream.forEach(value -> System.out.println(value + 1));
        //mapToDouble
        DoubleStream doubleStream = Stream.of("1.1", "2.2", "3.3").mapToDouble(Double::parseDouble);
        doubleStream.forEach(value -> System.out.println(value + 1));
        //flatMap
        Stream<List<Integer>> inputStream = Stream.of(
                Arrays.asList(1),
                Arrays.asList(2, 3),
                Arrays.asList(4, 5, 6)
        );
        Stream<Integer> outputStream = inputStream.flatMap(Collection::stream);
        outputStream.forEach(System.out::println);

        //reduce 这个方法的主要作用是把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce。例如 Stream 的 sum 就相当于
        String s = Stream.of("A", "B", "C", "D").reduce("A", String::concat);
        System.out.println(s);//AABCD
        //limit  返回 Stream 的前面 n 个元素
        Stream.of("A","B","c","d").limit(2).forEach(System.out::println);
       //skip 则是扔掉前 n 个元素
        Stream.of("A","B","c","d").skip(2).forEach(System.out::println);
      //min/max/distinct
        int min = Stream.of("1","2","3","4").mapToInt(Integer::valueOf).min().getAsInt();
        System.out.println(min);
        int max = Stream.of("1","2","3","4").mapToInt(Integer::valueOf).max().getAsInt();
        System.out.println(max);

        Stream.of("1","2","2","1","3").distinct().forEach(System.out::println);

Match
Stream 有三个 match 方法,从语义上说:

  • allMatch:Stream 中全部元素符合传入的 predicate,返回 true
  • anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true
  • noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true
        boolean result = Stream.of(1,18,20,30,100).allMatch(integer -> integer>10);
        System.out.println(result);
        result = Stream.of(1,18,20,30,100).anyMatch(integer -> integer>10);
        System.out.println(result);
        result = Stream.of(1,18,20,30,100).noneMatch(integer -> integer>10);
        System.out.println(result);

总之,Stream 的特性可以归纳为:

  • 不是数据结构
  • 它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。
  • 它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。
  • 所有 Stream 的操作必须以 lambda 表达式为参数
  • 不支持索引访问
  • 你可以请求第一个元素,但无法请求第二个,第三个,或最后一个。不过请参阅下一项。
  • 很容易生成数组或者 List
  • 惰性化
  • 很多 Stream 操作是向后延迟的,一直到它弄清楚了最后需要多少数据才会开始。
  • Intermediate 操作永远是惰性化的。
  • 并行能力
  • 当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并-
    行进行的。
  • 可以是无限的
  • 集合有固定大小,Stream 则不必。limit(n) 和 findFirst() 这类的 short-circuiting 操作可以对无限的 Stream 进行运算并很快完成。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353