Stream流的使用
一、stream流介绍
stream流结合了lambda表达式,简化了集合、数组的操作,其中lambda表达式简化了函数式接口中匿名内部类的创建。
关于lambda表达式、匿名内部类、函数式接口的内容具体看之前的文章
JAVA基础进阶(三):
Java编程基础:权限修饰符、final、枚举与抽象类、接口详解Java编程基础:权限修饰符、final、枚举与抽象类、接口详解
二、stream流的基本使用
2.1、stream流的使用步骤
1、首先得到一条stream流,再把数据放上去。
2、使用中间方法对数据进行处理
3、使用终结方法结束使用
2.2、stream流中filter、foreach的使用
将所有以"张“开头的元素存储到新集合中、把"张"开头的,长度为3的元素再存储到新集合中、遍历打印最终的结果
/**
* @throws Exception 1、将所有以"张“开头的元素存储到新集合中
* 2、把"张"开头的,长度为3的元素再存储到新集合中
* 3、遍历打印最终的结果
*/
@Test
public void test5() throws Exception {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
list.stream().filter(s -> s.startsWith("张")).
filter(s -> s.length() == 3).
forEach(s -> System.out.println("s = " + s));
}
filter表示steam流中的中间方法,返回值仍然为Stream类型,所以可以继续使用中间方法filter,
最后使用foreach终结方法返回值为void,这种编程方式称为链式编程。
第1个filter取出集合中"张"开头的所有元素,第2个filter取出剩下的集合中所有长度为3的元素,最后再打印集合中的元素
2.3、双列集合使用Sream流
2.2中的list集合是单列集合,可以直接使用Stream流,而像map这样的双列集合,需要先转换成单列集合,才能使用Stream流。
/**
* 双列集合必须先转化为单列集合,才能使用stream流
*
* @throws Exception
*/
@Test
public void test6() throws Exception {
HashMap<String, Integer> map = new HashMap<>();
map.put("aaa", 111);
map.put("bbb", 222);
map.put("ccc", 333);
map.put("ddd", 444);
//双列集合map,必须先转化为单列集合set
//map.keySet().stream().forEach(s -> System.out.println("s = " + s));
map.entrySet().stream().forEach(s -> System.out.println(s));
}
2.4、数组使用stream流
数组使用stream流,必须使用数组的工具Arrays中的stream方法
/**
* 数组使用stream流,必须使用数组的工具Arrays中的stream方法
*
* @throws Exception
*/
@Test
public void test7() throws Exception {
int[] arr = {1, 2, 4};
Arrays.stream(arr).forEach(value -> System.out.println("value = " + value));
String[] srr = {"a", "b", "c"};
Arrays.stream(srr).forEach(s -> System.out.println("s = " + s));
}
2.5、零散的数据使用stream流
需要注意的是当采用Stream.of方法,并且放入的是基本类型的数组时,返回的是数组的地址值
所以需要对数组采用stream流时,尽量不要采用Stream.of方法
Stream.of(1,2,4).forEach(value -> System.out.println("value = " + value));
Stream.of("a","b","c").forEach(s -> System.out.println("s = " + s));
//需要注意的是当采用Stream.of方法,并且放入的是基本类型的数组时,返回的是数组的地址值
//所以需要对数组采用stream流时,尽量不要采用Stream.of方法
int[] arr = {1, 2, 4};
Stream.of(arr).forEach(s -> System.out.println("s = " + s));
2.6、总结
1、单列集合(List、Set)可以直接使用Collection中的静态方法Stream
2、双列集合(Map)需要先转化为单列集合,再使用单列集合中的静态方法Stream。
3、数组需要使用Arrays工具类中的静态方法stream
4、零散数据可以直接使用Stream类中的静态方法of,数组尽量不要使用这个,具体的看2.5
三、 stream流中的中间方法
类似filter这样的中间方法还有limit、skip等,使用这些中间方法还能继续使用其他的中间方法,直到使用了终结方法。
stream流中的中间方法:skip、distinct、limit
/**
* stream流中的中间方法:skip、distinct
*/
@Test
public void test10() throws Exception {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
list.add("张三丰");
//1、首先去重,所以只剩下张无忌、周芷若、赵敏、张强、张三丰
//2、跳过前面两个数据,所以只剩下:赵敏、张强、张三丰
//3、只留下1个数据,所以只剩下:赵敏
list.stream()
.distinct()
.skip(2)
.limit(1)
.forEach(s -> System.out.println("s = " + s));
}
1、 首先去重,所以只剩下张无忌、周芷若、赵敏、张强、
2、跳过前面两个数据,所以只剩下:赵敏、张强、张三丰
3、只留下1个数据,所以只剩下:赵敏
四、stream流中的终结方法
使用了终结方法就不能再使用其他方法,常用的终结方法有下面几种
五、 将数据放到数组中和集合中
5.1、将数据放到数组中
/**
* stream流中的终结方法:forEach、count、toAarray
*/
@Test
public void test15() throws Exception {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
Object[] objects = list.stream().toArray();
System.out.println("数组为:" + Arrays.toString(objects));
}
5.2、将数据放到集合中
5.2.1、将数据放到list集合中
/**
* 流中的数据放到list集合中
*/
@Test
public void test16() throws Exception {
String[] arr = {"张无忌", "周芷若", "赵敏"};
List<String> list = Arrays.stream(arr).collect(Collectors.toList());
list.stream().forEach(s -> System.out.println("s = " + s));
}
5.2.2、将数据放到set集合中
/**
* 流中的数据放到set集合中
*/
@Test
public void test17() throws Exception {
String[] arr = {"张无忌", "周芷若", "赵敏"};
Set<String> set = Arrays.stream(arr).collect(Collectors.toSet());
set.stream().forEach(s -> System.out.println("s = " + s));
}
5.2.3、将数据放到map集合中
采用匿名内部类的形式
/**
* 流中的数据放到map集合中
*/
@Test
public void test18() throws Exception {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌-11");
list.add("周芷若-12");
list.add("赵敏-13");
Map<String, Integer> map = list.stream().collect(Collectors.toMap(new Function<String, String>() {
@Override
public String apply(String s) {
return s.split("-")[0];
}
}, new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.valueOf(s.split("-")[1]);
}
}));
map.entrySet().stream().forEach(stringIntegerEntry -> System.out.println("stringIntegerEntry = " + stringIntegerEntry));
}
采用lambda表达式的形式
/**
* 流中的数据放到map集合中
*/
@Test
public void test19() throws Exception {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌-11");
list.add("周芷若-12");
list.add("赵敏-13");
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap((s -> s.split("-")[0]), (s -> Integer.valueOf(s.split("-")[1]))));
map.entrySet().stream().forEach(stringIntegerEntry -> System.out.println("stringIntegerEntry = " + stringIntegerEntry));
}