Java8新特性----Stream
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8新特性----Stream相关的知识,希望对你有一定的参考价值。
What is Stream ?
注意:
Stream操作三部曲
使用演示:
/*
* Stream的三个操作步骤
*
* 1.创建stream
* 2.中间操作
* 3.终止操作(终端操作)
*
* */
@Test
void test()
{
//1.创建stream
//(1):可以通过collection系列集合提供的stream()或者parallelStream()
List<String> list=new ArrayList<>();
Stream<String> stream = list.stream();
//(2): 通过Arrays里面的静态方法stream()获取数据流
People[] peoples=new People[10];
Stream<People> stream1 = Arrays.stream(peoples);
//(3):通过stream里面的静态方法of()
Stream<String> aa = Stream.of("aa", "bb", "cc");
//(4):创建无限流
//迭代
Stream.iterate(0, (x) -> x + 2)
.limit(10)//中间操作
.forEach(System.out::println);
}
}
中间操作
筛选与切片
filter---接收Lambda,从流中排除某些元素
limit(max)---截断流,使其元素不超过给定数量
skip(n)---跳过元素,返回一个扔掉了前n个的元素的流,若流张元素不足n个,则返回一个空流,与limit(n)互补
distinct---筛选,通过流所生成的元素的hashcode()和equals()去重复元素
内部迭代: 迭代操作由Stream API完成
终止操作:一次性执行全部内容,即惰性求值
使用演示:
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("3号",19,5000),
new People("4号",20,3500)
);
@Test
void test()
{
//中间操作不会执行任何操作
Stream<People> s=peopleList.stream().filter(people ->people.getAge()>19);
//终止操作:一次性执行全部内容,即惰性求值
s.forEach(System.out::println);
}
}
外部迭代
//外部迭代
Iterator<People> iterator = peopleList.iterator();
while(iterator.hasNext())
System.out.println(iterator.next());
limit ===> 短路
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("3号",19,5000),
new People("4号",20,3500)
);
@Test
void test()
{
//当查询到满足条件的两条数据后,就停止迭代,此行为称为短路
peopleList.stream().
filter(people ->{
System.out.println("短路");
return people.getAge()>15;}).
limit(2).//短路
forEach(System.out::println);
}
}
skip ===>跳过前n个元素
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("3号",19,5000),
new People("4号",20,3500)
);
@Test
void test()
{
peopleList.stream().
filter(people ->{
System.out.println("短路");
return people.getAge()>15;}).
skip(2).
forEach(System.out::println);
}
}
distinct进行元素去重(自定义类需要重写对应的hashcode和equals方法)
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("2号",21,4000),
new People("4号",20,3500)
);
@Test
void test()
{
peopleList.stream().
distinct().
forEach(System.out::println);
}
}
映射
map–接收Lambda,将元素转换为其他形式或提取信息,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
flatMap—接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
map的使用演示:
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("2号",21,4000),
new People("4号",20,3500)
);
@Test
void test()
{
List<String> list=Arrays.asList("a","b","c");
//将原先集合里面的小写,全部转换为大写,并输出
list.stream().map((x)->x.toUpperCase()).forEach(System.out::println);
//对原先的流是没有影响的
System.out.println(list);
System.out.println("------------------------------------------------");
// peopleList.stream().map(p->p.getName());
//将原先集合里面的People元素全部转换为String元素
peopleList.stream().map(People::getName).forEach(System.out::println);
}
}
flatMap使用演示:
使用前,先看一下下面这个案例:
void test()
{
List<String> list=Arrays.asList("aaa","bbb","ccc");
Stream<Stream<Character>> sm = list.stream().map(TestMain::getAll);
//相当于当前sm大流里面存放了三个小流
sm.forEach(System.out::println);
}
public static Stream<Character> getAll(String str)
{
List<Character> list=new ArrayList<>();
for(Character ch:str.toCharArray())
{
list.add(ch);
}
return list.stream();
}
显然这里我们将list集合对应的新流中每一个元素,都映射为了一个流,并返回,相当于现在的大流中有三个小流
下面我们需要遍历这些小流,取出里面的值
void test()
{
List<String> list=Arrays.asList("aaa","bbb","ccc");
Stream<Stream<Character>> sm = list.stream().map(TestMain::getAll);
//遍历大流的同时,遍历小流,取出小流中的值
sm.forEach(x-> x.forEach(System.out::println));//效果{{a,a,a},{b,b,b},{c,c,c}}
}
public static Stream<Character> getAll(String str)
{
List<Character> list=new ArrayList<>();
for(Character ch:str.toCharArray())
{
list.add(ch);
}
return list.stream();
}
显然上面写法比较复杂,下面给出简化写法
@Test
void test()
{
List<String> list=Arrays.asList("aaa","bbb","ccc");
//返回值不在是大流嵌套小流,而是一个流
Stream<Character> characterStream = list.stream()
.flatMap(TestMain::getAll);// 效果{a,a,a,b,b,b,c,c,c}
characterStream.forEach(System.out::println);
}
public static Stream<Character> getAll(String str)
{
List<Character> list=new ArrayList<>();
for(Character ch:str.toCharArray())
{
list.add(ch);
}
return list.stream();
}
map与flatmap的区别
map是将对应的每个小流放入当前大流中构成一个流
flatmap取出集合中的每个元素放入当前的流中,相当于将每个小流里面的元素拿出来组合为一个大流
这里还可以参考add()和addAll()的关系:
List<String> list=Arrays.asList("aaa","bbb","ccc");
List list1=new ArrayList();
list1.add(list);
list1.addAll(list);
System.out.println(list1);
排序
sorted()—自然排序(Comparable)
sorted(Comparator com)—定制排序(Comparator)
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("2号",21,4000),
new People("4号",18,3500)
);
@Test
void test()
{
//这里people没有实现Comparable接口,因此没有自然排序的功能
//我们需要定制排序
peopleList.stream().sorted((x,y)->{
if(x.getAge()==y.getAge())
//money按照降序排列
return -x.money.compareTo(y.getMoney());
else
return x.getAge().compareTo(y.getAge());
}).forEach(System.out::println);
}
Stream的终止操作如下
查找与匹配
查找与匹配
allMatch--检查是否匹配所有元素
anyMatch---检查是否至少匹配一个元素
noneMatch---检查是否没有匹配所有元素
findFirst---返回第一个元素
findAny---返回当前流中任意元素
count---返回流中元素的总个数
max----返回流中最大值
min---返回流中最小值
演示:
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000, People.STATUS.BUSY),
new People("2号",21,4000, People.STATUS.FREE),
new People("2号",21,4000, People.STATUS.BUSY)以上是关于Java8新特性----Stream的主要内容,如果未能解决你的问题,请参考以下文章