流是什么
流是java API 的新成员,它允许你以声明的方式处理数据集合,可以把它看成遍历数据集的高级迭代器.此外,流还可以透明的并行处理,无需在写任何多线程代码了.流,用来处理数据
流简介
要讨论流,我们先谈谈集合,这是最容
和迭代器类似,流只能遍历一次.遍历完之后,我们就说这个流已经被消费掉了
例如:
public static void main(String[] args) {
List<String> list = Arrays.asList( "java8","in","action");
Stream<String> stream = list.stream();
stream.forEach(d -> System.out.println(d));
stream.forEach(d -> System.out.println(d));
}
//上述的代码会抛出**java.lang.IllegalStateException**
所以要记住,流只能消费一次.
内部迭代和外部迭代
使用Collection接口需要用户去做迭代(比如for-each),这成为外部迭代.相反,Stream库使用内部迭代–jvm帮你实现迭代,并且把得到的流存在了某个地方,你只要给出䘝函数说要干什么就可以了.
List<Person> list = new ArrayList<>();
Person p = null;
for(int i = 0 ; i< 10 ; i++){
p = new Person();
p.setAge(i);
p.setName("xiaoming"+i);
list.add(p);
}
//stream 内部迭代
List<String > names = list.stream()
.map(m -> m.getName())
.collect(Collectors.toList());
System.out.println(names);
流操作
java.util.stream.Stream中的Stream接口定义了很多操作.他们可以分为两大类:中间操作和终端操作.可以连接起来的操作成为中间操作,关闭流的操作成为终端操作.
中间操作:
filter
map
flatMap
limit
skip
sorted
distinct
终端操作
forEach
count
collect
allMatch
anyMatch
noneMatch
findFirst
findAny
使用硫
流的来分类: 数值流,来自文件和数据等多种来源的流,无限流
- 筛选
Streams 方法支持filter方法,该操作会接受一个谓词(一个返回boolean的函数)作为参数,并返回一个包括所有符合谓词的元素的流.
List<Person> list = new ArrayList<>();
Person person = null;
for(int i = 0 ; i< 10 ; i++){
person = new Person();
person.setAge(i);
person.setName("xiaoming"+i);
list.add(person);
}
List<Person > names = list.stream()
.filter(p -> p.getAge() < 2)
.collect(Collectors.toList());
System.out.println(names);
- 去重
Streams 支持distinct 方法用来进行去重工作
List<Integer> numbers = Arrays.asList(1,2,3,4,5,3,2,4,6,6,4,8);
numbers.stream()
.filter(n -> n%2 == 0)
.distinct()
.forEach( n -> System.out.println(n));
打印结果:2,4,6,8
- 截取
流支持limit(long)
// 截取操作
List<Integer> nums = Arrays.asList(1,3,4,5,2,4,5);
nums.stream()
.filter(n -> n>3)
.limit(2)
.forEach(n-> System.out.println(n));
//输出结果4,5
- 跳过元素
流支持skip(long),跳过前面n个元素
/*跳过元素*/
List<Integer> nums = Arrays.asList(1,3,4,5,6,6);
nums.stream()
.filter(n -> n > 3)
.skip(3)
.forEach(n -> System.out.println(n));
- 映射
map()
List<String> strs = Arrays.asList("caoyulong","huzhuohui","love");
strs.stream()
.map(String::length)
.forEach(i -> System.out.println(i));
//输出结果 9,9,4
- 合并映射
flatMap():生成的单个流和合并成一个流
String[] strs = {"hello","world"};
List<String> strList = Arrays.asList(strs);
strList.stream()
.map(w -> w.split(""))
.flatMap(Arrays::stream)
.distinct()
.forEach(c -> System.out.print(c));
//输出结果:helowrd
- 匹配
anyMatch allMatch
List<Person> list = new ArrayList<>();
Person person = null;
for(int i = 0 ; i < 10 ; i++){
person = new Person();
person.setName("caoyulong"+i);
person.setAge(i*10);
list.add(person);
}
System.out.println(list);
Boolean hasPerson = list.stream()
.anyMatch(p -> 0 == p.getAge());
if (hasPerson){
System.out.println("存在需要的person");
}else{
System.out.println("不存在需要的person");
}
findAny findFirst
List<Person> list = new ArrayList<>();
Person person = null;
for(int i = 0 ; i < 10 ; i++){
person = new Person();
person.setName("caoyulong"+i);
person.setAge(i*10);
list.add(person);
}
Optional<Person> res = list.stream()
.filter(p -> p.getAge() > 30)
.findAny();
System.out.println(res);
- 归纳
reduce
求和
List<Integer> nums = Arrays.asList(1,34,5,5,7);
int res = nums.stream()
.map(num -> num * num)
.reduce(0,(a,b) ->a+b);
System.out.println(res);
求积
//求乘积
List<Long> nums = Arrays.asList(1L,34L,5L,5L,7L);
Long res = nums.stream()
.map(n -> n*2)
.reduce(1L,(a,b) -> a*b);
System.out.println(res);