1、流的思想
可以想象成一条流水线,然后流水线上面有很多工序,不同的工序会对餐品进行检查,最后输出一个我们需要的餐品。
2、Stream流的作用
结合了Lambda表达式,简化集合、数组的操作。
3、Stream流的使用步骤:
①、先得到一条Stream流(流水线),并把数据放上去
②、利用Stream流中的API进行各种操作,其中包括:
过滤,转换 中间方法 方法调用完毕后还可以调用其它地方
统计,打印 终结方法 最后一步,方法调用完毕后不能调用其它地方
4、集合中获取流的方法
注意:如果是双列集合,需要调用keySet或者entrySet转换成单列集合,再获取流。
基本使用如下所示:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 5; i++) {
list.add(i + 1);
}
//使用Stream流
list.stream().forEach(n -> System.out.print(n));
System.out.println();
//双列结合
HashMap<String, Integer> person = new HashMap<>();
person.put("张三", 12);
person.put("李四", 18);
person.put("王二", 21);
//获取所有的键值
person.keySet().stream().forEach(n -> System.out.print(n + "\t"));
//第二种方式
person.entrySet().stream().forEach( n -> System.out.print(n + "\t"));
System.out.println();
//对于数组要调用Arrays里面的方法
int[] arr = new int[10];
Arrays.stream(arr).forEach(n -> System.out.print(n + "\t"));
System.out.println();
//对于一堆零散的数据
Stream.of(1,2,3,4,5).forEach(n -> System.out.print(n + "\t"));
}
}
输出结果:
12345 李四 张三 王二 李四=18 张三=12 王二=21 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5
5、Stream流的中间方法
方法如下所示:
注意:使用流修改数据后,并不会影响原来集合或者数组里面的数据!!!
import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
test05();
}
//测试filter方法
public static void test01() {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i + 1);
}
list.stream().filter(n -> n > 5).forEach(n -> System.out.print(n + "\t")); //6 7 8 9 10
System.out.println();
}
//测试limit方法
public static void test02() {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i + 1);
}
list.stream().limit(3).forEach(n -> System.out.print(n)); //1 2 3
}
//测试skip方法
public static void test03() {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i + 1);
}
list.stream().skip(8).forEach(n -> System.out.print(n + " ")); //9 10
}
//测试distinct方法
public static void test04() {
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("张三", 15));
list.add(new Student("李四", 18));
list.add(new Student("王二", 19));
list.add(new Student("张三", 15));
list.stream().distinct().forEach(n -> System.out.println(n)); //使用这种方法去重自定义数据类型,一定要重写Hashcode方法和equals方法!!
}
//测试Map方法
public static void test05() {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "周芷若-14", "赵敏-13", "张强-20", "张三丰-106", "张举-15", "张良-35", "王二麻子-31");
/**
* 需求: -后面的为人的年龄,现在需要把各个人的年龄提取出来
*/
// Function<String, Object>的第一个泛型为流本身的数据类型,第二个泛型为要转换为的数据类型
list.stream().map(new Function<String, Integer>() {
@Override
//这里的返回值类型表示要转换为的数据类型,s表示流中的每一个数据
public Integer apply(String s) {
String[] arr = s.split("-"); //将字符串按照"-"分开获得两个数组
String ageArr = arr[1];
int age = Integer.parseInt(ageArr);
return age;
}
}).forEach(n -> System.out.print(n + " ")); //14 13 20 106 15 35 31
System.out.println("\n----------------------------------");
//改成Lambda表达式形式
list.stream().map(s -> {
String[] arr = s.split("-"); //将字符串按照"-"分开获得两个数组
String ageArr = arr[1];
int age = Integer.parseInt(ageArr);
return age;
}).forEach(n -> System.out.print(n + " "));
System.out.println("\n----------------------------------");
//继续简化
list.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(n -> System.out.print(n + " "));
//输出:14 13 20 106 15 35 31
}
}
6、Stream流的终结方法(返回值为void的方法)
测试代码如下所示:
import java.util.*;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
test02();
}
public static void test01() {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "周芷若", "赵敏", "张强", "张三丰", "张举", "张良", "王二麻子");
//默认返回Object类型的数组
final Object[] array = list.stream().toArray();
for (Object o : array) {
System.out.print(o + " ");
}
System.out.println();
//测试count方法
System.out.println(list.stream().count());
//返回自定义数据类型的数组
//参数说明: IntFunction后面的泛型表示需要返回的数据类型 apply中的参数表示流中数据的个数,需要和数组长度保持一致,返回值表示需要的数据类型
String[] str1 = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(str1));
//改成Lambda表达式
String[] str2 = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(str2));
}
//测试collect方法
public static void test02() {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "周芷若-男-20", "王二麻子-女-23", "赵敏-女-22", "王富贵-男-30", "张强-男-14", "张三丰-男-19", "张举-男-23", "张良-女-25", "王镪-男-21", "王强-男-21");
//将指定规则的数据保存到一个List集合中
final List<String> myList = list.stream().filter(s -> s.startsWith("王")).collect(Collectors.toList());
System.out.println(myList);
//保存到Set集合中:可以去除重复元素
final Set<String> mySetList = list.stream().filter(s -> s.startsWith("王")).collect(Collectors.toSet());
System.out.println(mySetList);
System.out.println("------------------------------");
//保存到Map集合中
/**
* 说明:toMap后面为指定键值和value值的规则,其中Key的 Function中第一个泛型的数据类型为流中数据的数据类型,第二个数据类型为Key的数据类型
* value的 Function中的第一个泛型的数据类型为流中数据的数据类型,第二个数据类型为Key的数据类型
*
* Key的apply的形参:依次表示流中的数据,返回值为已经生成的键
* 注意点:如果要将数据收集到Map集合中,那么键不能够重复,如果有重复的就会报错!!!!!
*
* */
final Map<String, Integer> myMap1 = list.stream().filter(s -> s.startsWith("王")).
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.parseInt(s.split("-")[2]);
}
}));
System.out.println(myMap1);
System.out.println("------------------------------");
//改写成Lambda表达式
final Map<String, Integer> myMap2 = list.stream().filter(s -> s.startsWith("王")).
collect(Collectors.toMap(s -> s.split("-")[0],
s -> Integer.parseInt(s.split("-")[2]
)));
System.out.println(myMap2);
}
}
标签:Stream,stream,ArrayList,list,System,new,out
From: https://blog.51cto.com/u_15433911/7126090