JAVA8给我带了什么——流(入门)
JAVA8有一个新功能——流。笔者简单的看一下流。然后默默的闭上眼睛。感叹一声:这不是.NET里面的Linq吗?如果你们当中有谁做过.NET程序员的话,对于流的学习其实帮助是很大的。但是要明白你现在是在学JAVA的流。虽然他们的概念是有一点像。可是这也只是对你在理解流上面有一定的帮助。因为JAVA实现的方式却完成不一样子(不入流程序员的个人理解)。
好吧。那么流是什么呢?如果用书里面的方式解释的话,笔者可能也看不懂。做过开发的人员一般都会知道一些SQL语句吧,SELECT语句这个功能。相信大家一定都熟悉吧——SELECT是对数据库的数据进行操作。同样子JAVA也有数据啊。比如集合、数组。那么为什么JAVA不可能实现一套代码式的数据操作。如果这样子不知道大家会不会明白呢?(当然这不是官方,是不入流的程序员这样了理解的)
SQL语句里面有什么——SELECT、FORM、WHERE、ORDER BY、GROUP BY。这些都是对数据库里面数据操作的常规动作。JAVA8的流呢? 即然是流。那么说明必须把对应的数据变成一个流才行。关键方法stream()就是这个作用。 举例子来说明吧。笔者有一组字符数组,笔者相要查找出有含有 r 的字符。
package com.aomi; import java.util.Arrays;
import java.util.List; public class Main { public static void main(String[] args) {
// TODO Auto-generated method stub List<String> datas = Arrays.asList("red", "green", "bule"); datas
.stream()
.filter(s -> s.contains("r"))
.forEach(s -> System.out.println(s));
} }
运行结果:

让我们想想如果是以前的话,要什么样子去实现呢?
package com.aomi; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class Main { public static void main(String[] args) {
// TODO Auto-generated method stub List<String> datas = Arrays.asList("red", "green", "bule"); // datas
// .stream()
// .filter(s -> s.contains("r"))
// .forEach(s -> System.out.println(s)); List<String> vDatas = new ArrayList<>(); for (String str : datas) {
if (str.contains("r")) {
vDatas.add(str);
}
} for (String str : vDatas) {
System.out.println(str);
} } }
相对以前来讲很直观表现代码的意思。同时代码量又小很多。
- filter:用于过滤数据的,从下面的代码就可以明白,返回一个boolean型类的结果。
Stream<T> filter(Predicate<? super T> predicate);
- forEach:循环遍历回来的结果集合。代码看完就知道什么样子用了。
void forEach(Consumer<? super T> action);
JAVA的代很多都是很人性化的,所以只要从名字就可以明白他大概的功能了。
好了,笔者突然有一个想法——想要把时面的‘r’字符变成‘o’字符。
package com.aomi; import java.util.Arrays;
import java.util.List; public class Main { public static void main(String[] args) {
// TODO Auto-generated method stub List<String> datas = Arrays.asList("red", "green", "bule"); datas.stream()
.map(s -> s.replace('r', 'o'))
.forEach(s -> System.out.println(s)); } }
笔者去掉了filter方法,用了map。运行结果:

- map:相当于SQL中的 SELECT关键字有一点像。用于把结果变成你希望的样子。看一下代码
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
是一个function的函数式接口。函数描述符:T -> R。
显示这样子的例子有一点简单。在实际的开发过程中我们往往都是一大波数据对象。这样子笔者定义一个学生类。
package com.aomi;
public class Student {
private String name;
private int Sex;
private String phone;
private int score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSex() {
return Sex;
}
public void setSex(int sex) {
Sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
在来写一个数据源吧。
package com.aomi; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class Main { public static List<Student> getSources()
{
List<Student> students =new ArrayList<>(); Student stu1 = new Student(); stu1.setName("lucy");
stu1.setSex(0);
stu1.setPhone("13700227892");
stu1.setScore(9); Student stu2 = new Student();
stu2.setName("lin");
stu2.setSex(1);
stu2.setPhone("15700227122");
stu2.setScore(9); Student stu3 = new Student();
stu3.setName("lili");
stu3.setSex(0);
stu3.setPhone("18500227892");
stu3.setScore(8); Student stu4 = new Student(); stu4.setName("dark");
stu4.setSex(1);
stu4.setPhone("16700555892");
stu4.setScore(6); students.add(stu1);
students.add(stu2);
students.add(stu3);
students.add(stu4); return students;
} }
笔者定义了四个学生。这样子时候笔者想看看学分(Score)大于6同学的名字有哪一些。从上面代码我们可以看到除了第四个同学drak之后,其他都是合格的。 让我们看一下代码
package com.aomi; import java.util.ArrayList;
import java.util.List;
import static java.util.stream.Collectors.toList; public class Main { public static void main(String[] args) {
// TODO Auto-generated method stub List<Student> stus = getSources(); List<String> names = stus.stream()
.filter(stu -> stu.getScore() > 6)
.map(stu -> stu.getName())
.collect(toList()); for (String name : names) {
System.out.println(name);
} } public static List<Student> getSources() {
List<Student> students = new ArrayList<>(); Student stu1 = new Student(); stu1.setName("lucy");
stu1.setSex(0);
stu1.setPhone("13700227892");
stu1.setScore(9); Student stu2 = new Student();
stu2.setName("lin");
stu2.setSex(1);
stu2.setPhone("15700227122");
stu2.setScore(9); Student stu3 = new Student();
stu3.setName("lili");
stu3.setSex(0);
stu3.setPhone("18500227892");
stu3.setScore(8); Student stu4 = new Student(); stu4.setName("dark");
stu4.setSex(1);
stu4.setPhone("16700555892");
stu4.setScore(6); students.add(stu1);
students.add(stu2);
students.add(stu3);
students.add(stu4); return students;
} }
运行结果:

当我们看到这个例子的时候,我们就可以确定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)高到低排序并且只显示学生名和学分呢?
package com.aomi; import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList; import java.util.ArrayList;
import java.util.List; public class SMain { public static void main(String[] args) {
// TODO Auto-generated method stub List<Student> stus = getSources(); List<String> 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 List<Student> getSources() {
List<Student> students = new ArrayList<>(); Student stu1 = new Student(); stu1.setName("lucy");
stu1.setSex(0);
stu1.setPhone("13700227892");
stu1.setScore(9); Student stu2 = new Student();
stu2.setName("lin");
stu2.setSex(1);
stu2.setPhone("15700227122");
stu2.setScore(9); Student stu3 = new Student();
stu3.setName("lili");
stu3.setSex(0);
stu3.setPhone("18500227892");
stu3.setScore(8); Student stu4 = new Student(); stu4.setName("dark");
stu4.setSex(1);
stu4.setPhone("16700555892");
stu4.setScore(6); students.add(stu1);
students.add(stu2);
students.add(stu3);
students.add(stu4); return students;
}
}
运行结果:

关于上面sorted的用法。笔者上面已经讲过了。
现在笔者想看看男女各位的学习情况。又要如何。来分个组吧。
package com.aomi; import static java.util.stream.Collectors.groupingBy; import java.util.ArrayList;
import java.util.List; public class SMain { public static void main(String[] args) {
// TODO Auto-generated method stub List<Student> stus = getSources(); stus.stream()
.collect(groupingBy(ss -> ss.getSex())).
forEach((Integer sex, List<Student> students) -> {
System.out.println("sex:" + sex); for (Student student : students) {
System.out.println("name:" + student.getName() + " score:" + student.getScore());
}
}); } //去掉学生源的方法。太多了影响查看
}
结果:

即然都分组了。那就笔者在做一个业务。查看男女个组的人数。
package com.aomi; import static java.util.stream.Collectors.groupingBy; import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors; public class SMain { public static void main(String[] args) {
// TODO Auto-generated method stub List<Student> 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); }); }
......
.....//去掉数据源
..... }
运行结果:

在来一个分组之后,男女个组的总分。
package com.aomi; import static java.util.stream.Collectors.groupingBy; import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors; public class SMain { public static void main(String[] args) {
// TODO Auto-generated method stub List<Student> 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); }); } 。。。。。
}
运行结果:

通过这俩个例子,我们就可以明白一个道理。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流的思想。
JAVA8给我带了什么——流(入门)的更多相关文章
- JAVA8给我带了什么——流的概念和收集器
到现在为止,笔者不敢给流下定义,从概念来讲他应该也是一种数据元素才是.可是在我们前面的代码例子中我们可以看到他更多的好像在表示他是一组处理数据的行为组合.这让笔者很难去理解他的定义.所以笔者不表态.各 ...
- HDU 1532 最大流入门
1.HDU 1532 最大流入门,n个n条边,求第1点到第m点的最大流.只用EK做了一下. #include<bits/stdc++.h> using namespace std; #pr ...
- Java中的IO流 - 入门篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中的IO流-入门篇>,希望对大家有帮助,谢谢 由于Java的IO类有很多,这就导致我刚开始学的时候,感觉很乱,每次用到都是上网搜,结果 ...
- JAVA8给我带了什么——并行流和接口新功能
流,确定是笔者内心很向往的天堂,有他之后JAVA在处理数据就变更加的灵动.加上lambda表达不喜欢都不行.JAVA8也为流在提供另一个功能——并行流.即是有并行流,那么是不是也有顺序流.没有错.我前 ...
- 【BZOJ-2893】征服王 最大费用最大流(带下界最小流)
2893: 征服王 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 156 Solved: 48[Submit][Status][Discuss] D ...
- spring 缓存(spring自带Cache)(入门)源码解读
spring自带的缓存类有两个基础类:Cache(org.springframework.cache.Cache)类,CacheManager(org.springframework.cache.Ca ...
- hdu1532 (最大流入门,EK算法)
看着这个博客 然后敲了hdu1532这个入门题,算是对最大流有点理解了 #include <stdio.h> #include <string.h> #include < ...
- JAVA8给我带了什么——Optional和CompletableFuture
不管是JAVA,还是.NET.我们常常会看到空异常(NullPointerException).这种异常都是在运行的过程中出现.往往是变量是一个null值.但是你引用这个变量的后继字段或是方法.所以我 ...
- JAVA8给我带了什么——lambda表达
这此年来我一直从事.NET的开发.对于JAVA我内心深处还是很向往的.当然这并不是说我不喜欢.NET.只是觉得JAVA也许才是笔者最后的归处.MK公司是以.NET起家的.而笔者也因为兄弟的原因转行.N ...
随机推荐
- 一文让你完全弄懂Stegosaurus
国内关于 Stegosaurus 的介绍少之又少,一般只是单纯的工具使用的讲解之类的,并且本人在学习过程中也是遇到了很多的问题,基于此种情况下写下此文,也是为我逝去的青春时光留个念想吧~ Stegos ...
- FreeCAD源码初步了解
FreeCAD简介 FreeCAD是基于OpenCASCADE的开源CAD/CAE软件,完全开源(GPL的LGPL许可证),官方源码地址,详情可参考维基百科,百度百科等等. 如果要编译FreeCAD, ...
- PHP从入门到精通(六)
PHP中的错误处理 1.PHP的错误级别:见表格.2.调整PHP错误报告级别:PHP中,调整错误报告级别的方式有两种: ①修改PHP.ini文件的配置项.a.会导致在当前服务器环境下所有PHP文件都受 ...
- Python进阶量化交易专栏场外篇7- 装饰器计算代码时间
欢迎大家订阅<教你用 Python 进阶量化交易>专栏!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外已陆续推出一些手记来辅助同学们学习本专栏内容,目前已推出如下扩展篇: 在第一篇 ...
- Codeforces Round #503 (by SIS, Div. 2)-C. Elections
枚举每个获胜的可能的票数+按照花费排序 #include<iostream> #include<stdio.h> #include<string.h> #inclu ...
- 读书笔记(chapter3)
进程管理 3.1进程 1.进程:进程就是处于执行期的程序,实际上,进程就是正在执行的程序代码的实时结果: 2.执行线程,简称线程,是进程中活动的对象(每个线程拥有独立的程序计数器.进程栈.和一组进程寄 ...
- Fastdfs文件服务器搭建
安装FastDFS之前,先安装libevent工具包.然后要安装libfastcommon和FastDFS,还要依赖nginx来显示图片. 1安装libevent yum -y install lib ...
- Dynamic Routing Based On Redis
Dynamic Routing Based On Redis Ngnix技术研究系列2-基于Redis实现动态路由 上篇博文我们写了个引子: Ngnix技术研究系列1-通过应用场景看Nginx的反 ...
- [区块链]POW 与POS
POW:全称Proof ofWork,工作证明. 这是什么意思呢?就是说,你能获得多少货币,取决于你挖矿贡献的有效工作,也就是说,你电脑性能越好,分给你的矿就会越多,这就是根据你的工作证明来执行货币的 ...
- Xshell 使用数字小键盘进行vim 写入操作.
Copy From http://blog.csdn.net/shenzhen206/article/details/51200869 感谢原作者 在putty或xshell上用vi/vim的时候,开 ...