Java - lambda我也能学会

我们首先看一个java实现多线程的lambda表达式的例子

常规

Runnable runnable = new Runnable(){
            @Override
            public void run() {
                System.out.println("多线程");
            }};

lambda形式

Runnable runnable = () -> {
            System.out.println("多线程");
        };

简洁
此方法使用的场景只能是实现的方法中只有一行语句。

Runnable runnable = () -> System.out.println("多线程");

Lambda在Collections中的用法

public class StreamExample {

    public static void main(String[] args) {

        List<Integer> myList = new ArrayList<>();
        for(int i=0; i<100; i++) myList.add(i);

        //有序流
        Stream<Integer> sequentialStream = myList.stream();

        //并行流
        Stream<Integer> parallelStream = myList.parallelStream();

        //使用lambda表达式,过滤大于90的数字
        Stream<Integer> highNums = parallelStream.filter(p -> p > 90);
        //lambdag表达式 forEach循环
        highNums.forEach(p -> System.out.println("最大数 并行="+p));

        Stream<Integer> highNumsSeq = sequentialStream.filter(p -> p > 90);
        highNumsSeq.forEach(p -> System.out.println("最大数 有序="+p));

    }

}

输出结果

最大数 并行=91
最大数 并行=96
最大数 并行=93
最大数 并行=98
最大数 并行=94
最大数 并行=95
最大数 并行=97
最大数 并行=92
最大数 并行=99
最大数 有序=91
最大数 有序=92
最大数 有序=93
最大数 有序=94
最大数 有序=95
最大数 有序=96
最大数 有序=97
最大数 有序=98
最大数 有序=99

为什么要使用Lambda表达式

1.简化代码行数
2.顺序执行或并行执行
以下为例子之间的对照

//传统形式
private static boolean isPrime(int number) {
    if(number < 2) return false;
    for(int i=2; i<number; i++){
        if(number % i == 0) return false;
    }
    return true;
}
//使用表达式的
private static boolean isPrime(int number) {
    return number > 1
            && IntStream.range(2, number).noneMatch(
                    index -> number % index == 0);
}

为了更好的可读性,我们还可以这么写

private static boolean isPrime(int number) {
    IntPredicate isDivisible = index -> number % index == 0;

    return number > 1
            && IntStream.range(2, number).noneMatch(
                    isDivisible);
}

我们来看一个计算数字集合总合的例子,它有一个参数将用来传递表达式后处理得到最终的结果。

public static int sumWithCondition(List<Integer> numbers, Predicate<Integer> predicate) {
        return numbers.parallelStream()
                .filter(predicate)
                .mapToInt(i -> i)
                .sum();
    }

比如我们将传递这样的如下条件

//统计所有数字总合
sumWithCondition(numbers, n -> true)
//统计所有偶数总合
sumWithCondition(numbers, i -> i%2==0)
//统计所有大于5的总合
sumWithCondition(numbers, i -> i>5)

接下来我再来看一个更加偷懒的Lambda表达式

//找出3-11之间最大的奇数,并求它的平方
private static int findSquareOfMaxOdd(List<Integer> numbers) {
        int max = 0;
        for (int i : numbers) {
            if (i % 2 != 0 && i > 3 && i < 11 && i > max) {
                max = i;
            }
        }
        return max * max;
    }

我们使用Lambada重写它

class NumberTest{
    public static int findSquareOfMaxOdd(List<Integer> numbers) {
            return numbers.stream()
                    .filter(NumberTest::isOdd)
                    .filter(NumberTest::isGreaterThan3)
                    .filter(NumberTest::isLessThan11)
                    .max(Comparator.naturalOrder())
                    .map(i -> i * i)
                    .get();
        }

        public static boolean isOdd(int i) {
            return i % 2 != 0;
        }

        public static boolean isGreaterThan3(int i){
            return i > 3;
        }

        public static boolean isLessThan11(int i){
            return i < 11;
        }
}

Lambada表达式例子

() -> {}                     // 没有参数,没有返回值

() -> 42                     // 没有参数,方法体有表达式
() -> null                   // 没有参数,方法体有表达式
() -> { return 42; }         // 没有参数,方法体有返回值
() -> { System.gc(); }       // 没有参数,有方法体

// 有多种返回值
() -> {
  if (true) return 10;
  else {
    int result = 15;
    for (int i = 1; i < 10; i++)
      result *= i;
    return result;
  }
}

(int x) -> x+1             // 单个参数
(int x) -> { return x+1; } // 单个参数,跟上面一样
(x) -> x+1                 // 单个参数,跟下面一样
x -> x+1

(String s) -> s.length()
(Thread t) -> { t.start(); }
s -> s.length()
t -> { t.start(); }

(int x, int y) -> x+y      // 多个参数,有返回值
(x,y) -> x+y               // 跟上面一样
(x, final y) -> x+y        // 多个参数,有不能修改的参数
(x, int y) -> x+y          // 这个是非法的,不能混合写

方法跟构造函数可以用下面这种方式

System::getProperty
System.out::println
"abc"::length
ArrayList::new
int[]::new

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • 我们首先看一个java实现多线程的lambda表达式的例子 常规 lambda形式 简洁此方法使用的场景只能是实现...
    大猪大猪阅读 304评论 0 3
  • 我们首先看一个java实现多线程的lambda表达式的例子 常规 lambda形式 简洁此方法使用的场景只能是实现...
    kikiki2阅读 151评论 0 2
  • 我们首先看一个java实现多线程的lambda表达式的例子 常规 lambda形式 简洁此方法使用的场景只能是实现...
    kikiki2阅读 132评论 0 1
  • 我们首先看一个java实现多线程的lambda表达式的例子 常规 lambda形式 简洁此方法使用的场景只能是实现...
    大猪大猪阅读 337评论 0 5
  • 我们首先看一个java实现多线程的lambda表达式的例子 常规 lambda形式 简洁此方法使用的场景只能是实现...
    kikiki5阅读 202评论 0 2