java 8是什么_JAVA8给我带了什么——流(入门)

本文介绍了Java 8引入的新特性——流(Stream),通过对比.NET的Linq,阐述了流的基本概念和用法。通过实例展示了如何使用filter、map和forEach等方法对数据进行操作,以及如何利用collect进行数据收集。此外,还探讨了sorted、groupingBy等方法在数据排序和分组中的应用,进一步揭示了Java 8流与SQL操作的相似性。文章深入浅出地讲解了流的使用,帮助读者更好地理解和掌握这一强大的新特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JAVA8有一个新功能——流。笔者简单的看一下流。然后默默的闭上眼睛。感叹一声:这不是.NET里面的Linq吗?如果你们当中有谁做过.NET程序员的话,对于流的学习其实帮助是很大的。但是要明白你现在是在学JAVA的流。虽然他们的概念是有一点像。可是这也只是对你在理解流上面有一定的帮助。因为JAVA实现的方式却完成不一样子(不入流程序员的个人理解)。

好吧。那么流是什么呢?如果用书里面的方式解释的话,笔者可能也看不懂。做过开发的人员一般都会知道一些SQL语句吧,SELECT语句这个功能。相信大家一定都熟悉吧——SELECT是对数据库的数据进行操作。同样子JAVA也有数据啊。比如集合、数组。那么为什么JAVA不可能实现一套代码式的数据操作。如果这样子不知道大家会不会明白呢?(当然这不是官方,是不入流的程序员这样了理解的)

SQL语句里面有什么——SELECT、FORM、WHERE、ORDER BY、GROUP BY。这些都是对数据库里面数据操作的常规动作。JAVA8的流呢? 即然是流。那么说明必须把对应的数据变成一个流才行。关键方法stream()就是这个作用。 举例子来说明吧。笔者有一组字符数组,笔者相要查找出有含有 r 的字符。

1 packagecom.aomi;2

3 importjava.util.Arrays;4 importjava.util.List;5

6 public classMain {7

8 public static voidmain(String[] args) {9 //TODO Auto-generated method stub

10

11 List datas = Arrays.asList("red", "green", "bule");12

13 datas14 .stream()15 .filter(s -> s.contains("r"))16 .forEach(s ->System.out.println(s));17 }18

19 }

运行结果:

386a89064477b65bba483f498d5f4055.png

让我们想想如果是以前的话,要什么样子去实现呢?

1 packagecom.aomi;2

3 importjava.util.ArrayList;4 importjava.util.Arrays;5 importjava.util.List;6

7 public classMain {8

9 public static voidmain(String[] args) {10 //TODO Auto-generated method stub

11

12 List datas = Arrays.asList("red", "green", "bule");13

14 //datas15 //.stream()16 //.filter(s -> s.contains("r"))17 //.forEach(s -> System.out.println(s));

18

19 List vDatas = new ArrayList<>();20

21 for(String str : datas) {22 if (str.contains("r")) {23 vDatas.add(str);24 }25 }26

27 for(String str : vDatas) {28 System.out.println(str);29 }30

31 }32

33 }

相对以前来讲很直观表现代码的意思。同时代码量又小很多。

filter:用于过滤数据的,从下面的代码就可以明白,返回一个boolean型类的结果。

Stream filter(Predicate super T> predicate);

forEach:循环遍历回来的结果集合。代码看完就知道什么样子用了。

void forEach(Consumer super T> action);

JAVA的代很多都是很人性化的,所以只要从名字就可以明白他大概的功能了。

好了,笔者突然有一个想法——想要把时面的‘r’字符变成‘o’字符。

1 packagecom.aomi;2

3 importjava.util.Arrays;4 importjava.util.List;5

6 public classMain {7

8 public static voidmain(String[] args) {9 //TODO Auto-generated method stub

10

11 List datas = Arrays.asList("red", "green", "bule");12

13 datas.stream()14 .map(s -> s.replace('r', 'o'))15 .forEach(s ->System.out.println(s));16

17 }18

19 }

笔者去掉了filter方法,用了map。运行结果:

1811e252ed2fd72b996ef2367aee939e.png

map:相当于SQL中的 SELECT关键字有一点像。用于把结果变成你希望的样子。看一下代码

Stream map(Function super T, ? extends R> mapper);

是一个function的函数式接口。函数描述符:T -> R。

显示这样子的例子有一点简单。在实际的开发过程中我们往往都是一大波数据对象。这样子笔者定义一个学生类。

packagecom.aomi;public classStudent {privateString name;private intSex;privateString phone;private intscore;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}public intgetSex() {returnSex;

}public void setSex(intsex) {

Sex=sex;

}publicString getPhone() {returnphone;

}public voidsetPhone(String phone) {this.phone =phone;

}public intgetScore() {returnscore;

}public void setScore(intscore) {this.score =score;

}

}

在来写一个数据源吧。

1 packagecom.aomi;2

3 importjava.util.ArrayList;4 importjava.util.Arrays;5 importjava.util.List;6

7 public classMain {8

9 public static ListgetSources()10 {11 List students =new ArrayList<>();12

13 Student stu1 = newStudent();14

15 stu1.setName("lucy");16 stu1.setSex(0);17 stu1.setPhone("13700227892");18 stu1.setScore(9);19

20 Student stu2 = newStudent();21 stu2.setName("lin");22 stu2.setSex(1);23 stu2.setPhone("15700227122");24 stu2.setScore(9);25

26 Student stu3 = newStudent();27 stu3.setName("lili");28 stu3.setSex(0);29 stu3.setPhone("18500227892");30 stu3.setScore(8);31

32 Student stu4 = newStudent();33

34 stu4.setName("dark");35 stu4.setSex(1);36 stu4.setPhone("16700555892");37 stu4.setScore(6);38

39

40 students.add(stu1);41 students.add(stu2);42 students.add(stu3);43 students.add(stu4);44

45 returnstudents;46 }47

48 }

笔者定义了四个学生。这样子时候笔者想看看学分(Score)大于6同学的名字有哪一些。从上面代码我们可以看到除了第四个同学drak之后,其他都是合格的。 让我们看一下代码

1 packagecom.aomi;2

3 importjava.util.ArrayList;4 importjava.util.List;5 import staticjava.util.stream.Collectors.toList;6

7 public classMain {8

9 public static voidmain(String[] args) {10 //TODO Auto-generated method stub

11

12 List stus =getSources();13

14 List names =stus.stream()15 .filter(stu -> stu.getScore() > 6)16 .map(stu ->stu.getName())17 .collect(toList());18

19 for(String name : names) {20 System.out.println(name);21 }22

23 }24

25 public static ListgetSources() {26 List students = new ArrayList<>();27

28 Student stu1 = newStudent();29

30 stu1.setName("lucy");31 stu1.setSex(0);32 stu1.setPhone("13700227892");33 stu1.setScore(9);34

35 Student stu2 = newStudent();36 stu2.setName("lin");37 stu2.setSex(1);38 stu2.setPhone("15700227122");39 stu2.setScore(9);40

41 Student stu3 = newStudent();42 stu3.setName("lili");43 stu3.setSex(0);44 stu3.setPhone("18500227892");45 stu3.setScore(8);46

47 Student stu4 = newStudent();48

49 stu4.setName("dark");50 stu4.setSex(1);51 stu4.setPhone("16700555892");52 stu4.setScore(6);53

54 students.add(stu1);55 students.add(stu2);56 students.add(stu3);57 students.add(stu4);58

59 returnstudents;60 }61

62 }

运行结果:

dd4f5d8be759d002f4959e85941b22f7.png

当我们看到这个例子的时候,我们就可以确定map是做什么。就是用于最后确定返回数据类型。在这个代码中。笔者又用到了一个叫collect的方法。

collect:用于收集数据的功能。即是把相关的数据汇总成为另一种数据。

笔者传入是toList()方法。把最后数据变成一个集合。这个方法是Collectors类的一个静态方法。当然Collectors类里面有很多静态方法。如果你们去看一下他的代码。你就会发现他的方法名字好像都是在对数据操作的样子。没有错。以后我们开发过程都会用到Collectors类的方法集。

记得引用下面代码

import static java.util.stream.Collectors.toList;

从上面的几个例子来看。让笔者感觉如下

stream相关于SQL里面的FROM

filter相当于SQL里面的WHERE.

map相当于SQL里面的SELECT

那么其他呢?比如 order by或 group by 。让我们接着看吧。

现在笔者想在按学分(Score)高到低排序并且只显示学生名和学分呢?

packagecom.aomi;import staticjava.util.Comparator.comparing;import staticjava.util.stream.Collectors.toList;importjava.util.ArrayList;importjava.util.List;public classSMain {public static voidmain(String[] args) {//TODO Auto-generated method stub

List stus =getSources();

List names =stus.stream()

.sorted(comparing(Student::getScore).reversed())

.map(stu-> "学名:"+stu.getName()+" 学分:"+stu.getScore())

.collect(toList());for(String name : names) {

System.out.println(name);

}

}public static ListgetSources() {

List students = new ArrayList<>();

Student stu1= newStudent();

stu1.setName("lucy");

stu1.setSex(0);

stu1.setPhone("13700227892");

stu1.setScore(9);

Student stu2= newStudent();

stu2.setName("lin");

stu2.setSex(1);

stu2.setPhone("15700227122");

stu2.setScore(9);

Student stu3= newStudent();

stu3.setName("lili");

stu3.setSex(0);

stu3.setPhone("18500227892");

stu3.setScore(8);

Student stu4= newStudent();

stu4.setName("dark");

stu4.setSex(1);

stu4.setPhone("16700555892");

stu4.setScore(6);

students.add(stu1);

students.add(stu2);

students.add(stu3);

students.add(stu4);returnstudents;

}

}

运行结果:

1c3271ad0bfa9c043392ed46aee24efe.png

关于上面sorted的用法。笔者上面已经讲过了。

现在笔者想看看男女各位的学习情况。又要如何。来分个组吧。

1 packagecom.aomi;2

3 import staticjava.util.stream.Collectors.groupingBy;4

5 importjava.util.ArrayList;6 importjava.util.List;7

8 public classSMain {9

10 public static voidmain(String[] args) {11 //TODO Auto-generated method stub

12

13 List stus =getSources();14

15 stus.stream()16 .collect(groupingBy(ss ->ss.getSex())).17 forEach((Integer sex, List students) ->{18 System.out.println("sex:" +sex);19

20 for(Student student : students) {21 System.out.println("name:" + student.getName() + " score:" +student.getScore());22 }23 });24

25 }26

27 //去掉学生源的方法。太多了影响查看

28 }

结果:

9377155cc7a6eac551ea7b24162b42c2.png

即然都分组了。那就笔者在做一个业务。查看男女个组的人数。

packagecom.aomi;import staticjava.util.stream.Collectors.groupingBy;importjava.util.ArrayList;importjava.util.List;importjava.util.stream.Collectors;public classSMain {public static voidmain(String[] args) {//TODO Auto-generated method stub

List stus =getSources();

stus.stream().collect(groupingBy(ss->{if (ss.getSex() == 0)return "女";else

return "男";

}, Collectors.counting()))

.forEach((String sex, Long count)->{

System.out.println("sex:" + sex + " count:" +count);

});

}

......

.....//去掉数据源

.....

}

运行结果:

01262ff61bb5bc6d49ff012a698b44fd.png

在来一个分组之后,男女个组的总分。

packagecom.aomi;import staticjava.util.stream.Collectors.groupingBy;importjava.util.ArrayList;importjava.util.List;importjava.util.stream.Collectors;public classSMain {public static voidmain(String[] args) {//TODO Auto-generated method stub

List stus =getSources();

stus.stream().collect(groupingBy(ss->{if (ss.getSex() == 0)return "女";else

return "男";

}, Collectors.summingLong(t->t.getScore())))

.forEach((String sex, Long sum)->{

System.out.println("sex:" + sex + " count:" +sum);

});

}

。。。。。

}

运行结果:

c5f8cffd0ecb2ea20620c903a33fdc90.png

通过这俩个例子,我们就可以明白一个道理。groupingBy的第二个参数,是一个任何型类的收集器。也就是说分组之后,你可以在进行对分组之后的结果进处理。

好了。你们有没有感觉跟SQL语句的功能很像呢?如下

stream相关于SQL里面的FROM

filter相当于SQL里面的WHERE.

map相当于SQL里面的SELECT

sorted相当于SQL里面的Order BY

Collectors.groupingBy相当于SQL里面的GROUP BY

Collectors.summingLong相当于SQL里面的SUM函数。只不过他又加了一步结果转为Long类型

Collectors.counting相当于SQL里面的COUNT函数

理解了上面代码的基础用法的概念之后,我们接下要一步步去看看JAVA8流的思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值