Stream流简化集合操作

Stream流

  • JDK8新增的一套API(java.util.stream.*),可以用于操作集合或数组的数据
  • 本身结合Lambda的语法风格,功能强,性能高,代码简洁,可读性行高。

体验

/**
 * 需求:
 * 从这个集合中,找出名称三个字并切姓张的人,并且存放到一个新的集合中
 */
public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无鸡");
        list.add("周星驰");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("陈雨轩");
    }
}

传统做法

//首先创建一个容器用来存储名称
List<String> newList = new ArrayList<>();
//使用增强for来遍历集合
for (String name : list){
    // 如果首字母为“张”,并且长度为3,则存放到新容器中
    if (name.startsWith("张") && name.length() == 3)
        newList.add(name);
}
System.out.println(newList);

使用Stream流的做法

List<String> newList2 = list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).collect(Collectors.toList());

我们发现只需要一行代码即可完成需求,并且可读性也很高

通过这个案例我们可以大致了解Stream流的使用步骤

  1. 首先我们需要准备一个数据源,也就是有一个可以被操作的集合。
  2. 获取Stream流,就像一条流水线能与数据源建立连接。
  3. 调用流水线的各种方法,对数据进行处理。
  4. 对结果进行遍历、统计、收集到新容器。

获取Stream流

获取集合的Stream流

Collection提供的方法说明
default Stream< E> stream()获取当前集合对象的stream流

获取数组的Stream流

Arrays类提供的方法说明
public static < T> Stream< T> stream(T[ ] array)获取当前数组的stream流
Stream类提供的方法说明
public static< T> Stream< T> of(T… values)获取当前接收数据的Stream流
public class Test {
    public static void main(String[] args) {
    	Collection<String> list = new ArrayList<String>();
        Stream<String> s1 = list.stream();
        
        // Map 集合,获取Stream流
        Map<String, Integer> map = new HashMap<>();
        map.stream(); // 不属于Collection实现类
        //但是可以获得键流
        Set<String> keys = map.keySet();
        Stream<String> stream = keys.stream();
        
        //获取值流
        Collection<Integer> values = map.values();
        Stream<Integer> stream1 = values.stream();

        //获取键值对流
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        Stream<Map.Entry<String, Integer>> stream2 = entries.stream();
        
        //数组流
        String[] names = {"张无鸡","周星驰","赵敏","张强","张三丰","陈雨轩"};
        Stream<String> stream3 = Arrays.stream(names);
        System.out.println(stream3.count());//返回流中元素的个数

        Stream<String> stream4 = Stream.of(names);
    }
}

Stream流的常用方法

中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)

Stream提供的中间方法说明
Stream< T> filter(Predicate< ? super T> predicate)用于对流中的数据进行过滤
Stream< T> sorted()对元素进行升序排序
Stream< T> sorted(Comparetor< ? super T> comparator)按照指定规则进行排序
Stream< T> limit(long maxSize)获取前几个元素
Stream< T> skip(long n)跳过前几个元素
Stream< T> distinct()去除流中重复的元素
< R> Stream< R> map(Function< ? super T ? extends R> mapper)对元素进行加工,并返回对应的新流
static < T> Stream< T> concat(Stream a, Stream b)和并ab两个流为一个流
//依然是对上面名称集合过滤,可以使用第一个方法
list.stream().filter(s -> s.startsWith("张") && s.length() == 3).forEach(System.out::println);

//对元素排序
List<Double> scores = new ArrayList<>();
scores.add(66.6);
scores.add(77.7);
scores.add(99.9);
scores.add(88.8);

//升序排序
scores.stream().sorted().forEach(System.out::println);
//降序排序
scores.stream().sorted((d1,d2) -> Double.compare(d2,d1)).forEach(System.out::println);

//加工方法 / 映射方法 , 把原先的数据取出加工后再放回
scores.stream().map(s -> "加10分" + (s + 10)).forEach(System.out::println);

//合并流,合并姓名和分数流
Stream(Object) s3 = Stream.concat(list,scores);

终结方法

终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了。

Stream提供的终结方法说明
void forEach(Consumer action)对流运算后的元素执行遍历
long count()统计流中元素个数
Optional< T> max(Comparator< ? super T> comparator)获取流中最大值元素
Optional< T> min(Comparator< ? super T> comparator)获取流中最大值元素
//forEach
//前面使用到很多次遍历打印

//统计个数
long count = list.stream().count();

//获取最大值
Optional<Double> max = scores.stream().max((t1,t2) -> Double.compare(t1 , t2));
//获取Optional对象中的元素
Double maxScore = max.get();

收集Stream流

将结果放回集合或数组中。

Stream提供的终结方法说明
R collect(Collector collector)把流的结果收集到指定集合中
Object[] toArray()把流的结果收集到数组中
Collectors工具类提供的收集方法说明
public static < T> Collector toList()将元素收集到List集合中
public static < T> Collector toSet()把元素收集到Set集合中
public static Collector toMap(Function keyMapper, Function valueMapper)把元素收集到Map集合中
//还是名称List list
//收集性张的人名到新的集合中
List<String> list1 =  list.stream().filter(s -> s.startWith("张")).collect(Collectors.toList());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值