ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java8 Stream流

2022-08-08 15:02:12  阅读:535  来源: 互联网

标签:stream Stream list System add println Java8 out


Stream流

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

image-20220808103626965

1 起始操作

在 Java 8 中, 集合接口有两个方法来生成流:

  • stream() − 为集合创建串行流。
  • parallelStream() − 为集合创建并行流。

生成流

// 为集合创建串行流
Stream<String> stream = list.stream();

// 为集合创建并行流
Stream<String> stream = list.parallelStream();

2 中间操作

过滤器

public class Demo01 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素。
        List<String> list = new ArrayList<>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");
        /*
            filter()方法是中间操作,中间操作都用lambda表达式。
         */

        //需求1:把list集合中以“张”开头的元素在控制台输出。
        System.out.println("======需求1=====");
        list.stream().filter(x -> x.startsWith("张")).forEach(System.out::println);

        //需求2:把list集合中长度为3的元素在控制台输出。
        System.out.println("======需求2=====");
        list.stream().filter(x -> x.length() == 3).forEach(System.out::println);

        //需求3:把list集合中以“张”开头的,长度为3的元素在控制台输出。
        System.out.println("======需求3=====");
        //在一个过滤器中要满足两个条件。
        list.stream().filter(x -> x.startsWith("张") && x.length() == 3).forEach(System.out::println);
        System.out.println("-----");
        //用两个过滤器,先过滤出以“张”开头的元素,再过滤出长度为3的元素。
        list.stream().filter(x -> x.startsWith("张")).filter(x -> x.length() == 3).forEach(System.out::println);
    }
}

理解stream流的时候,可以顺便复习复习lambda表达式。

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)

限制、跳过

/*
    中间操作
        限制:limit()
        跳过:skip()
 */
public class Demo02 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素。
        List<String> list = new ArrayList<>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:取前3个数据在控制台输出。
        System.out.println("======需求1======");
        list.stream().limit(3).forEach(System.out::println);
        //需求2:跳过3个元素,把剩下的元素在控制台输出。
        System.out.println("=====需求2=======");
        list.stream().skip(3).forEach(System.out::println);
        //需求3:跳过2个元素,把剩下的元素中前2个在控制台输出。
        System.out.println("=====需求3======");
        //先用一个skip(2)跳过前两个元素,在剩下的元素中用limit(2)取前两个元素并输出。
        list.stream().skip(2).limit(2).forEach(System.out::println);
    }
}

合并流、去重

/*
    中间操作
        合并流:concat()------这是一个静态方法。Stream.concat()
        去重:distinct()

 */
public class Demo03 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素。
        List<String> list = new ArrayList<>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:取前4个数据组成一个流。
        Stream<String> stream1 = list.stream().limit(4);
        //需求2:跳过2个数据组成一个流。
        Stream<String> stream2 = list.stream().skip(2);
        //需求3:合并需求1和需求2得到的流,并把结果在控制台输出。
        //合并流的方法concat()是一个静态方法。
        Stream.concat(stream1, stream2).forEach(System.out::println);

        //需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复。
        Stream.concat(stream1, stream2).distinct().forEach(System.out::println);
    }
}

排序

/*
    中间操作
        自然排序:sorted()
        用比较器比较排序:sorted(Comparator comparator)
 */
public class Demo04 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素。
        List<String> list = new ArrayList<>();
        list.add("linqingxia");
        list.add("zhangmanyu");
        list.add("wangzuxian");
        list.add("liuyan");
        list.add("zhangming");
        list.add("zhangwuji");

        //需求1:按照字母顺序把数据在控制台输出。
        System.out.println("====需求1====");
        list.stream().sorted().forEach(System.out::println);
        //需求2:按照字符串长度把数据在控制台输出。
        System.out.println("====需求2====");
        //前面-后面:从小到大    后面-前面:从大到小
        list.stream().sorted((s1, s2) -> s1.length() - s2.length()).forEach(System.out::println);
        //需求3:先按照长度,再按照字母顺序排序。
        System.out.println("====需求3====");
        list.stream().sorted((s1, s2) -> {
            int sort1 = s1.length() - s2.length();
            int sort2 = sort1 == 0 ? s1.compareTo(s2) : sort1;
            return sort2;
        }).forEach(System.out::println);
    }
}

返回此流元素组成的流

/*
    中间操作
        返回此流元素组成的流:map()
        IntSteam mapToInt()   返回一个IntSteam类型的结果
 */
public class Demo05 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("10");
        list.add("20");
        list.add("30");
        list.add("40");
        list.add("50");

        //需求:将集合中的字符串数据转换为整数之后在控制台输出。
        System.out.println("====需求1====");
        list.stream().map(x->Integer.parseInt(x)).forEach(System.out::println);
        //以上方法可以改进。
        System.out.println("====需求1改进====");
        list.stream().map(Integer::parseInt).forEach(System.out::println);
        //以上方法还可以改进。
        System.out.println("====需求1再改进====");
        //用第3个
        list.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
        //求和
        int sum = list.stream().mapToInt(Integer::parseInt).sum();
        System.out.println("求和:" + sum);
    }
}

3 终结操作

输出

/*
    终结操作
        输出:forEach()
        返回流中的元素数:count()
 */
public class Demo06 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素。
        List<String> list = new ArrayList<>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:把集合中的元素在控制台输出。
        System.out.println("====需求1====");
        list.stream().forEach(System.out::println);
        //需求2:统计集合中有几个以“张”开头的元素,并把统计结果在控制台输出。
        System.out.println("====需求2====");
        long count = list.stream().filter(x -> x.startsWith("张")).count();
        System.out.println(count);
    }
}

收集操作

map只是把一个新的流转换为一个新的流,而collect的把流转换为集合。

/*
    Stream流的收集操作

 */
public class Demo08 {
    public static void main(String[] args) {
        //创建List集合对象
        List<String> list = new ArrayList<>();
        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        //需求1:得到名字为3个字的流
        Stream<String> stream = list.stream().filter(x -> x.length() == 3);
        //需求2:把使用Stream流操作完毕的数据收集到List集合中并遍历。
        List<String> collectList = stream.collect(Collectors.toList());
        System.out.println("=====List=====");
        for (String string : collectList) {
            System.out.println(string);
        }

        //创建Set集合对象。
        Set<Integer> set = new HashSet<>();
        set.add(10);
        set.add(20);
        set.add(30);
        set.add(40);
        //需求3:得到大于25的流
        Stream<Integer> integerStream = set.stream().filter(x -> x > 25);
        //需求4:把使用Stream流操作完毕的数据收集到Set集合中并遍历。
        Set<Integer> collectSet = integerStream.collect(Collectors.toSet());
        System.out.println("=====Set=====");
        //Set集合是无序的,输出无序。
        for (Integer integer : collectSet) {
            System.out.println(integer);
        }

        //定义一个字符串数组。
        String string[] = {"林青霞,1", "张曼玉,2", "王祖贤,3", "柳岩,4"};
        //需求5:得到字符串中数据大于2的流。
        Stream<String> stringStream = Stream.of(string).filter(x -> Integer.parseInt(x.split(",")[1]) > 2);
        //需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,序号作值。
        Map<String, Integer> integerMap = stringStream.collect(Collectors.toMap(x -> x.split(",")[0], x -> Integer.parseInt(x.split(",")[1])));
        Set<String> ketSet = integerMap.keySet();
        System.out.println("=====Map=====");
        for (String str : ketSet) {
            Integer value = integerMap.get(str);
            System.out.println(str + "=" + value);
        }
    }
}

4 练习

/*
    Stream流的练习
        现在有两个 ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
        1.男演员只要名字为3个字的前三人
        2.女演员只要姓林的,井且不要第一个
        3.把过滤后的男演员姓名和女演员姓名合并到一起
        4.把上一步操作后的元素作为构造方法的参数创建演员对象遍历数据
            演员类Actor已经提供,里面有一个成员变量,一个带参造方法,以及成员变量对应的 get/set方法
 */
public class Demo01 {
    public static void main(String[] args) {
        //男演员集合
        List<String> manList = new ArrayList<>();
        manList.add("周润发");
        manList.add("成龙");
        manList.add("刘德华");
        manList.add("吴京");
        manList.add("周星驰");
        manList.add("李连杰");
        //女演员集合
        List<String> womanList = new ArrayList<>();
        womanList.add("林心如");
        womanList.add("张曼玉");
        womanList.add("林青霞");
        womanList.add("柳岩");
        womanList.add("林志玲");
        womanList.add("王祖贤");

        System.out.println("================方法1================");
        Stream<String> manListStream = manList.stream().filter(name -> name.length() == 3).limit(3);
        
        Stream<String> womanListStream = womanList.stream().filter(name -> name.startsWith("林")).skip(1);
        
        Stream<String> concatStream = Stream.concat(manListStream, womanListStream);
        
        concatStream.map(name -> new Actor(name)).forEach(System.out::println);
        // concatStream.map(Actor::new).forEach(System.out::println);
        
        System.out.println("================方法2================");
        Stream.concat(manList.stream().filter(x -> x.length() == 3).limit(3)
                , womanList.stream().filter(x -> x.startsWith("林")).skip(1))
                .map(Actor::new)
                .forEach(System.out::println);
    }
}

class Actor {
    private String name;

    public Actor() {
    }

    public Actor(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Actor{" +
                "name='" + name + '\'' +
                '}';
    }
}

参考资料:Java 8 Stream | 菜鸟教程 (runoob.com)

标签:stream,Stream,list,System,add,println,Java8,out
来源: https://www.cnblogs.com/Kled/p/16561888.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有