Java之Stream流

先看一个小案例体验一下stream流有多方便

案例:创建一个集合,把集合所有以"张"开头的元素存储到一个新集合中,再把"张"开头的集合中的长度为3的元素存储到新的集合中,最后遍历得到的集合。

传统方式:

public class StreamDemo {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张三丰");
        list1.add("张益达");
        list1.add("李逍遥");
        list1.add("张良");
        list1.add("小张");
        ArrayList<String> list2 = new ArrayList<>();
        for (String s : list1) {
            if (s.startsWith("张")) {
                list2.add(s);
            }
        }
        ArrayList<String> list3 = new ArrayList<>();
        for (String s : list2) {
            if (s.length() == 3) {
                list3.add(s);
            }
        }
        for (String s : list3) {
            System.out.println(s);
        }
    }
}

使用Stream流

        list1.stream().filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3)
                .forEach(s -> System.out.println(s));

对比下来,使用Stream流写起来太简单啦!

Stream流的三类方法

获取Stream流

创建一条流水线,并把数据放到流水线上准备进行操作。

中间方法

流水线上的操作。一次操作完毕后,还可以继续进行其他操作。

终结方法

一个Stream流只能有一个终结方法。

使用场景

单列集合

使用Collection接口中的默认方法stream()

//单列集合 
ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("sss");
        list.add("vvv");
        list.stream().forEach(s -> System.out.println(s));

控制台结果

 

双列集合

通过keySet或entrySet获取Set集合再获取Stream流

        //双列集合
        HashMap<String, Integer> hm = new HashMap<>();
        hm.put("sdad", 20);
        hm.put("hgkj", 23);
        hm.put("wert", 26);
        hm.put("dsgfsg", 29);
        hm.keySet().stream().forEach(System.out::println);
        hm.entrySet().stream().forEach(System.out::println);

控制台结果

 

数组

Arrays中的静态方法stream生成流

 //数组
        int[] arr = {1,2,3,4,5};
        Arrays.stream(arr).forEach(System.out::println);

同种数据类型的多个数据

1,2,3,4,5...

"aaa" "bbb" "ccc"...

使用Stream.of(T...values)生成流

Stream.of(1,2,3,4,5).forEach(System.out::println);

中间操作方法filter

public class StreamDemo1 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张益达");
        list.add("李逍遥");
        list.add("张良");
        list.add("小张");
      //filter方法获取流中的每一个数据
        //test 方法中的s,依次表示流中的每一个数据
        //我们只要在test方法中对s进行判断就可以了
        //如果判断的结果为true,则当前的数据留下
        //如果判断的结果为false,则当前数据就不要
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("张");
            }
        });

        //predicate接口中只有一个抽象方法test 所以我们可以使用lambda表达式来简化
        list.stream().filter((String s) -> s.startsWith("张"));
    }
}

其他中间操作方法

Stream <T> limit (long maxSize) : 截取指定参数个数的数据

Stream <T> skip (long n) : 跳过指定参数个数的数据

static <T> Stream<T> concat (Stream a, Stream b) : 合并a和b两个流为一个流

Stream <T> distinct () : 去除流中重复的元素。依赖hashcode和equals方法

public class StreamDemo1 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张益达");
        list.add("李逍遥");
        list.add("张良");
        list.add("张良");
        list.add("小张");
        list.add("小张");
        list.add("小张");
        
        //  Stream <T> limit (long maxSize) : 截取指定参数个数的数据
        list.stream().limit(2).forEach(s -> System.out.println(s));

        //  Stream <T> skip (long n) : 跳过指定参数个数的数据
        list.stream().skip(2).forEach(s -> System.out.println(s));

        //  static <T> Stream<T> concat (Stream a, Stream b) : 合并a和b两个流为一个流
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("萨达");
        list2.add("春辉");
        list2.add("饭馆");
        Stream<String> stream2 = list2.stream();
        Stream<String> stream1 = list.stream();
        Stream.concat(stream1, stream2).forEach(s -> System.out.println(s));
        //  Stream <T> distinct () : 去除流中重复的元素。依赖hashcode和equals方法
        list.stream().distinct().forEach(s -> System.out.println(s));

    }
}

终结操作方法

import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class StreamDemo2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张益达");
        list.add("李逍遥");
        list.add("张良");
       list.stream().forEach(new Consumer<String>() {
           @Override
           public void accept(String s) {
               System.out.println(s);
           }
       });

        //   list.stream().forEach(System.out::println);
        //long count():返回此流中的元素数
        long count = list.stream().count();
        System.out.println(count);
    }
}

stream流的收集操作

import java.util.ArrayList;
import java.util.function.Predicate;

/**
 * 定义一个集合,并添加一些指数1,2,3,4,5,6,7,8,9,10
 * 将集合中的奇数删除,只保留偶数
 * 遍历集合得到2,4,6,8,10
 */
public class StreamDemo3 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
             for (int i = 1; i <= 10; i++) {
            list.add(i);
        }
//        list.stream().filter(new Predicate<Integer>() {
//            @Override
//            public boolean test(Integer integer) {
//                if(integer%2==0){
//                    return true;
//                }
//                return false;
//            }
//        });

//        list.stream().filter((Integer integer)-> {
//            if(integer%2==0){
//                return true;
//            }
//            return false;
//        }).forEach(System.out::println);

 list.stream().filter((Integer integer)-> integer % 2 == 0).forEach(System.out::println);
    }
}

遍历集合发现,集合并未发生变化。

结论:stream流中无法直接修改集合,数组等数据源中的数据

收集方法

.collect(Collectors.toList())

.collect(Collectors.toSet())

/**
 * 定义一个集合,并添加一些指数1,2,3,4,5,6,7,8,9,10
 * 将集合中的奇数删除,只保留偶数
 * 遍历集合得到2,4,6,8,10
 */
public class StreamDemo4 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }
        list.add(10);
        list.add(10);
        List<Integer> list1 = list.stream().filter((Integer integer) -> integer % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(list1);

        Set<Integer> set = list.stream().filter((Integer integer) -> integer % 2 == 0).collect(Collectors.toSet());
        System.out.println(set);
    }
}

.collect(Collectors.toMap())

/**
 * Stream流的收集方法
 * 创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
 * "zhangsan,23"
 * "lisi,24"
 * "wangwu,25"
 * 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
 */
public class StreamDemo5 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("zhangsan,23");
        list.add("lisi,24");
        list.add("wangwu,25");
        Map<String, Integer> map = list.stream().filter((String s) -> {
            String[] split = s.split(",");
            int age = Integer.parseInt(split[1]);
            return age >= 24;
        }).collect(Collectors.toMap(
                (String s) -> {
                    return s.split(",")[0];
                },
                (String s) -> {
                    return Integer.parseInt(s.split(",")[1]);
                }
        ));
        //遍历map
       for(Map.Entry<String,Integer> entry : map.entrySet()) {
           String key = entry.getKey();
           Integer value = entry.getValue();
           System.out.println((key + ":" + value));
       }
    }
}

练习

现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

  • 男演员只要名字为3个字的前三人

  • 女演员只要姓林的,并且不要第一个

  • 把过滤后的男演员姓名和女演员姓名合并到一起

  • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

/**
 现在有两个ArrayList集合,
 分别存储6名男演员名称和6名女演员名称,
 要求完成如下的操作

 - 男演员只要名字为3个字的前三人
 - 女演员只要姓林的,并且不要第一个
 - 把过滤后的男演员姓名和女演员姓名合并到一起
 - 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
 **/
public class ActorTest {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
        list1.add("周润发");
        list1.add("成龙");
        list1.add("刘德华");
        list1.add("吴京");
        list1.add("周星驰");
        list1.add("李连杰");

        list2.add("邱淑贞");
        list2.add("林小林");
        list2.add("林青霞");
        list2.add("柳岩");
        list2.add("宋茜");
        list2.add("王祖贤");

        //男演员只要名字为3个字的前三人
        List<String> manList = list1.stream().filter(s -> s.length()==3).limit(3).collect(Collectors.toList());
        System.out.println(manList);
        //女演员只要姓林的,并且不要第一个
        List<String> womanList = list2.stream().filter(s -> s.startsWith("林")).skip(1).collect(Collectors.toList());
        System.out.println(womanList);
        //把过滤后的男演员姓名和女演员姓名合并到一起
        Stream<String> stream = Stream.concat(manList.stream(), womanList.stream());
        //把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
        stream.forEach(name->{
            Actor actor = new Actor(name);
            System.out.println(actor);
        });
    }
}

最后,祝您身体健康,再见

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值