Stream流就像工厂中的流水线操作。
如何使用Stream?
1、首先要获取Stream流,那么如何获取呢?
对于不同的数据,有不同的获取方法。
①单列集合
方法名 | 说明 |
---|---|
default Stream<E> stream() | Collection接口中的默认方法 |
所以实现了Collection接口的集合类对象可直接调用stream()方法。
代码实现:
public class StreamDemo1 {public static void main(String[] args) {// 1.首先创建一个单列集合ArrayList<String> list = new ArrayList<>();Collections.addAll(list,"a","b");// 2.获取流list.stream().forEach(s-> System.out.println(s));}
}
②双列集合
双列集合无法直接获取流,需先转换为单列集合再获取流。
代码实现:
public class StreamDemo2 {public static void main(String[] args) {//1.创建一个普通的Map集合HashMap<String, String> hm = new HashMap<>();hm.put("张三", "南京");hm.put("李四", "北京");hm.put("王五", "上海");hm.put("赵六", "北京");hm.put("孙七", "深圳");hm.put("周八", "杭州");hm.put("吴九", "宁波");hm.put("郑十", "苏州");hm.put("刘一", "无锡");hm.put("陈二", "嘉兴");hm.put("林三", "天津");Set<Map.Entry<String, String>> entries = hm.entrySet();entries.stream().forEach(s -> System.out.println(s.getKey() + ":" + s.getValue()));}
}
而双列集合转变为单列集合有两种方式,分别是keySet()和entrySet()两个方法。
hm.keySet().stream().forEach(s -> System.out.println(s));hm.entrySet().stream().forEach(s -> System.out.println(s));
输出结果:可以看到第一种只输出了键,而第二种键和值都输出了。
③数组
代码实现:
public class StreamDemo3 {public static void main(String[] args) {int[] arr = {1,2,3,4};Arrays.stream(arr).forEach(s -> System.out.println(s));}
}
④零散的数据
这个就不演示了。
方法中的形参如果是可变参数,在传递实参时既可以是多个数据,也可以传递数组。
2、获取了Stream流之后自然可以使用Stream流提供的各种方法了。
方法也分为两种,第一种是可继续流向下面的;第二种是直接终结的。
中间方法:方法的返回值为一个新的stream流,可以继续对数据进行操作。
方法名 | 说明 |
---|---|
Stream<T> filter(Predicate predicate) | 用于对流中的数据进行过滤 |
Stream<T> limit(long maxSize) | 截取前n个数据组成流并返回 |
Stream<T> skip(long n) | 跳过前n个,返回由剩余元素组成的流 |
static <T> Stream<T> concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
Stream<T> distinct() | 去重并返回去重后的元素组成的流 |
<R> Stream<R> map(Function<? super T, ? extends R> mapper) | 转换流中的数据类型 |
两个细节:
- 中间方法每次使用都会返回新的stream方法,可以使用链式编程。
- 修改stream流中的数据不会影响集合或者数组中原来的数据。
filter方法的形参为匿名内部类的对象,可使用lambda表达式进行简化,当方法体中的返回值为true时将此数据留下,false则舍去。
contact方法中两个流中数据的类型尽量相同,当不同时会自动将类型提升为a和b的共同父类。
distinct底层调用了equals和hashCode方法,所以如果存储的是自定义对象,要重写这两个方法。
map方法:将数据转换为另外一种类型,传递的参数为匿名内部类的对象。
list.add("谢广坤-16");
list.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.println(s));
终结方法:由于这种方法的返回类型不是Stream,所以执行完此方法之后,就不能再执行Stream流中的方法了。
常见方法
方法名 | 说明 |
---|---|
void forEach(Consumer action) | 对此流的每个元素执行操作 |
long count() | 返回此流中的元素数 |
收集方法:把操作完的stream流中的数据装到集合中去。
常用方法
方法名 | 说明 |
---|---|
R collect(Collector collector) | 把结果收集到集合中 |
工具类Collectors提供了具体的收集方式
方法名 | 说明 |
---|---|
public static <T> Collector toList() | 把元素收集到List集合中 |
public static <T> Collector toSet() | 把元素收集到Set集合中 |
public static Collector toMap(Function keyMapper,Function valueMapper) | 把元素收集到Map集合中 |
注意:Set和Map集合中不能有重复元素。
toMap方法中分别要设置键和值。