show me the code and take to me,做的出来更要说的明白

GitHub项目JavaHouse同步收录

喜欢就点个赞呗! 你的支持是我分享的动力!

引入

是否有遇到看不懂身边同事代码的情况,是否有被面试官问到 Java 新特性不懂的情况。我掐指一算你大概是遇到的了 Lambda 表达式 和 Stream 流。为了解决上述情况,我特地献上一份关于 Lambda 和 Stream 的指南,以解燃煤之急。

Lambda

普通调用

首先我们先看第一个例子。


@Test
public void test(){
test1(1);
} private void test1(int a){
System.out.println(a);
}

运行Test,输出结果

1

相信这里大家都很清楚,我不需要多废话!

内部类调用

那我们在来看看第二个例子

public interface IPerson {
void personMethod();
} private void test2(IPerson person){
person.personMethod();
} @Test
public void test2(){
test2(new IPerson(){
@Override
public void personMethod() {
System.out.println(1);
}
});
}

运行Test,输出结果

1

这里的话我将参变成了一个接口,使用了内部类。大家是不是觉得这种形式的代码不容易看清楚,一个参数竟然放了这么多东西,真是让人头大啊。所以我们有了 Lambda 表达式。

Lambda 重构

我们使用 Lambda 表达式重写上面代码。得到下面新代码:

public interface IPerson {
void personMethod();
} private void test2(IPerson person){
person.personMethod();
} @Test
public void test2(){
test2(() -> System.out.println(1));
}

运行Test,输出结果

1

这样的代码是不是比使用内部类代码优雅了很多,看起来舒服极了,关键代码也少了。这就是 Lambda 表达式的魅力。

Lambda 调用

好了,经过上面的层层递进的例子,我们引出了 Lambda 表达式。现在我们开始了解 Lambda 表达式的语法。

语法:

->

是的,他的调用语法就是一个箭头。当然这样说的话我也不太信。其实还没说完。

当我们的方法没有参数的时候,没有返回,他需要保留括号,形式如下:

() -> System.out.println(1);

当有一个参数的时候,没有返回,小括号可以去掉,形式如下

a -> System.out.println(a)

当有多个参数的时候以及方法里面的语法多余一行的时候,没有返回,,形式如下:

(a, b) -> {
System.out.println(a);
System.out.println(b);
}

上面例子都是没有返回的,那么有返回又是怎样的呢?形式如下:

a -> {
System.out.println(a);
return a;
}

是的,那就加一下返回啊。

函数式接口

其实上面都是展示如果去调用,不知道你们是否发现后者感觉到,他没有方法名就去调用了,是不是接受不了。这是正常情况。因为我们调用的接口里面这有一个方法,所以我们只需要一个 ->就可以调用到接口里面方法。

所以我们如果想自己写一个 Lambda 的话。只需要在接口里面写一个抽象方法即可。举了例子:

public interface IPerson {
int personMethod(int a);
}

当然我建议加一个注解@FunctionalInterface,形式如下:

@FunctionalInterface
public interface IPerson {
int personMethod(int a);
}

这样就是限制接口里面只能有一个抽象方法了。这个就叫函数式接口。当我们再继续往里面加的话,就会报错了:

其实大多数情况下,我们不需要自己写函数式接口。因为 Java 已经内置了四种常见的函数式接口。

这四个接口需要一般与 Stream 一起使用。

Stream

普通迭代

我们直接看代码,一个普通的迭代例子

public class StreamTest {
@Test
public void test2(){
List list = Arrays.asList(1, 2, 3, 4, 5);
int count = 0;
for (Object o : list){
count ++;
}
System.out.println(count);
}
}

运行Test,输出结果

5

在 Java8 之前,我们统计 list 的大小是上面的形式。

Stream 重构

现在我们用 Stream 重构上面的代码

public class StreamTest {
@Test
public void test3(){
List list = Arrays.asList(1, 2, 3, 4, 5);
long count = list.stream().count();
System.out.println(count);
}
}

运行Test,输出结果

5

瞬间感觉代码清爽了很多,变得优雅了,关键代码也少了。这就是 Stream 的魅力。

经过上面的例子,我们可以感觉到 Stream 可以代替 for 循环,进行特定操作。注意这里是特定的操作,因为 Stream 接口里面只有只封了几个方法。

collect()

collect() 方法可以将 Stream 变成 List等集合形式。

我们看一个例子:

public class StreamTest {
@Test
public void test4(){
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5,1);
List<Integer> collect = stream.collect(Collectors.toList());
}
}

fiter()

fiter() 方法与 Predicate 函数接口一起使用。

不想看文字,还有图片

该方法可以过滤出特定元素并且返回原来的类型。举一个例子

public class StreamTest {
@Test
public void test5(){
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5,1);
List<Integer> collect = stream.filter(a -> a > 3).collect(Collectors.toList());
System.out.println(Arrays.asList(collect));
}
}

运行Test,输出结果

[[4, 5]]

map()

map() 方法与 Function 函数接口一起使用。

不想看文字,还有图片

该方法可以将原来的集合进行修改,包括返回类型,然后返回一个新的集合。举一个例子

public class StreamTest {
@Test
public void test8(){
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5,1);
List<Integer> collect = stream.map(a -> a = 1).collect(Collectors.toList());
// List<Boolean> collect = stream.map(a -> a == 1).collect(Collectors.toList());
System.out.println(Arrays.asList(collect));
}
}

运行Test,输出结果

[[1, 1, 1, 1, 1, 1]]

我们可以看到两种情况 Integer -> Integer 以及 Integer -> Boolean

注意我们不能操作同一个 stream 两次,不然会报错,有兴趣可以试试。

distinct()

该方法意如其字,就是去重。代码如下

public class StreamTest {
@Test
public void test7(){
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5,1);
List<Integer> collect = stream.distinct().collect(Collectors.toList());
System.out.println(Arrays.asList(collect));
}
}

运行Test,输出结果

[[1, 2, 3, 4, 5]]

关注微信公众号,随时移动端阅读

基础之Lamada和Stream的邂逅的更多相关文章

  1. 基础才是重中之重~stream和byte[]的概念与转化

    回到目录 多看几篇 之所以写这篇文章完全是因为最近在研究FastDFS这个分布式的文件存储系统,当然这不是我第一次研究它了,就像我们去看一本书,我们不会只看一篇,而是一次次,一篇篇,每看一次会有新的收 ...

  2. JAVA基础知识|lambda与stream

    lambda与stream是java8中比较重要两个新特性,lambda表达式采用一种简洁的语法定义代码块,允许我们将行为传递到函数中.之前我们想将行为传递到函数中,仅有的选择是使用匿名内部类,现在我 ...

  3. 漫漫人生路-学点Jakarta基础-Java8新特性 Stream/Lambda

    背景 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk dat ...

  4. java基础(10)---stream流

    一.stream的应用场景 for遍历的冗余场景:  stream的写法: 二.获取Stream流的常用方式 三.Stream的map映射方法 更简单的写法: 四.Stream的filter过滤方法 ...

  5. 基础篇:JAVA.Stream函数,优雅的数据流操作

    前言 平时操作集合数据,我们一般都是for或者iterator去遍历,不是很好看.java提供了Stream的概念,它可以让我们把集合数据当做一个个元素在处理,并且提供多线程模式 流的创建 流的各种数 ...

  6. java基础第11期——Stream流、方法引用、junit单元测试

    1.Stream流 Stream流与io流是不同的东西,用于解决集合类库已有的弊端, 1.1 获取Stream流: Collection集合的Stream方法,注意Map集合要经过转化 default ...

  7. 性能篇系列—stream详解

    Stream API Java 8集合中的Stream相当于高级版的Iterator Stream API通过Lambda表达式对集合进行各种非常便利高效的聚合操作,或者大批量数据操作 Stream的 ...

  8. Spring Cloud Alibaba - Spring Cloud Stream 整合 RocketMQ

    Spring Cloud Stream 简介 在微服务的开发过程中,可能会经常用到消息中间件,通过消息中间件在服务与服务之间传递消息,不管你使用的是哪款消息中间件,比如RabbitMQ.Kafka和R ...

  9. C# 中的Stream流

    流就是一个类的对象,很多文件的输入输出操作都以类的成员函数的方式来提供: 流其实是一种信息的转换,是有序的,有输入和输出流(IO); 1.FileStream 文件流,读取和保存文件操作使用: //写 ...

随机推荐

  1. python3中的zip函数

    zip函数的作用: zip函数接受任意多个可迭代对象作为参数,将对象中对应的元素打包成一个tuple,然后返回一个可迭代的zip对象. 这个可迭代对象可以使用循环的方式列出其元素 若多个可迭代对象的长 ...

  2. Liunx vi/vim 2

    移动光标的方法 H 光标移动到这个屏幕的最上方那一行的第一个字符 M  光标移动到这个屏幕的中央那一行的第一个字符 L 光标移动到这个屏幕的最下方那一行的第一个字符 G 移动到这个档案的最后一行(常用 ...

  3. Python 基础02 基本数据类型

    简单的数据类型以及赋值 变量不需要声明 Python的变量不需要声明,你可以直接输入: >>> a = 10 那么你的内存里就有了一个变量a,它的值是10,它的类型是 integer ...

  4. 2019-8-31-dotnet-通过-WMI-获取系统信息

    title author date CreateTime categories dotnet 通过 WMI 获取系统信息 lindexi 2019-08-31 16:55:59 +0800 2019- ...

  5. Redis源码解析:02链表

    链表提供了高效的节点重排能力,以及顺序性的节点访问方式,因为Redis使用的C语言并没有内置这种数据结构,所以Redis自己实现了链表. 链表在Redis中的应用非常广泛,比如列表的底层实现之一就是链 ...

  6. 亿级消息系统的核心存储:Tablestore发布Timeline 2.0模型

    背景 互联网快速发展的今天,社交类应用.消息类功能大行其道,占据了大量网络流量.大至钉钉.微信.微博.知乎,小至各类App的推送通知,消息类功能几乎成为所有应用的标配.根据场景特点,我们可以将消息类场 ...

  7. vue element 给指数的div加loading

     const loading = this.$loading({       lock: true,       text: 'Loading',       spinner: 'el-icon-lo ...

  8. chrome谷歌浏览器怎么清除指定网站cookie

    https://jingyan.baidu.com/article/fa4125aced30cc28ac709230.html 在使用电脑的情况下,由于到部分网站的cookie的问题导致的部分功能失效 ...

  9. ReactDOM & DOM Elements

    一.ReactDOM 1.1 render() ReactDOM.render(element,container,[callback]) 在container中渲染一个React元素,然后返回组件一 ...

  10. lrj 9.4.1 最长上升子序列 LIS

    p275 d(i)是以Ai为结尾的最长上升子序列的长度 <算法竞赛入门经典-训练指南>p62 问题6 提供了一种优化到 O(nlogn)的方法. 文本中用g(i)表示d值为i的最小状态编号 ...