• Java---Stream流详解


    目录​​​​​​​

    一、Stream流详解

    二、Stream流的获取

    (1)单列集合

    (2)双列集合

    (3)数组

    (4)一些零散数据

    三、Stream流中常用的API方法

    (1)中间方法

    (2)终结方法

    (3)收集方法


    一、Stream流详解

    Stream流其实就相当于是工厂上的流水线,后面会对数据更好的进行操作,如打印,过滤等等。说到底把它比作是工厂上的流水线还是很形象的。

    二、Stream流的获取

    1. 获取方式 方法名 说明
    2. 单列集合 defaultstream() collection中的默认方法
    3. 双列集合 无 无法直接使用stream流
    4. 数组 public staticStreamstream(T[] array) Array工具类的静态方法
    5. 一堆零散数据 public staticStreamof(T...values) Stream接口中的静态方法

    (1)单列集合

    1. package article;
    2. import java.util.*;
    3. import java.util.Collection;
    4. import java.util.*;
    5. import java.util.function.Consumer;
    6. import java.util.*;
    7. import java.util.*;
    8. public class first {
    9. public static void main(String[] args) {
    10. ArrayLists=new ArrayList<>();
    11. Collections.addAll(s, "opop","------","4er45","<>><><");
    12. s.stream().forEach(new Consumer() {
    13. @Override
    14. public void accept(String t) {
    15. // TODO 自动生成的方法存根
    16. System.out.println(t);
    17. }
    18. });
    19. //接下来使用lambda表达式进行简化
    20. System.out.println("--------------------------------");
    21. s.stream().forEach(i->System.out.println(i));
    22. }
    23. }

    (2)双列集合

    双列结合获取stream流有两种办法,一种是获取通过键获取,一种是通过键值来获取。

    1. package article;
    2. import java.util.*;
    3. import java.util.Collection;
    4. import java.util.Map.Entry;
    5. import java.util.*;
    6. import java.util.function.Consumer;
    7. import java.util.*;
    8. import java.util.*;
    9. public class first {
    10. public static void main(String[] args) {
    11. HashMap s=new HashMap<>();
    12. s.put("abs", 192);
    13. s.put("<<<<",200);
    14. s.put("[][][]", 10);
    15. //第一种通过键获取stream流
    16. s.keySet().stream().forEach(new Consumer(){
    17. @Override
    18. public void accept(String t) {
    19. // TODO 自动生成的方法存根
    20. //t是键
    21. System.out.println("键="+t+" 值="+s.get(t));
    22. }
    23. });
    24. System.out.println("----------------------------------------------------");
    25. //第二种通过键值对获取
    26. s.entrySet().stream().forEach(new Consumer>() {
    27. @Override
    28. public void accept(Entry t) {
    29. // TODO 自动生成的方法存根
    30. System.out.println("键="+t.getKey()+" 值="+t.getValue());
    31. }
    32. });
    33. }
    34. }

    (3)数组

    1. package article;
    2. import java.util.*;
    3. import java.util.Collection;
    4. import java.util.Map.Entry;
    5. import java.util.*;
    6. import java.util.function.Consumer;
    7. import java.util.function.IntConsumer;
    8. import java.util.*;
    9. import java.util.*;
    10. public class first {
    11. public static void main(String[] args) {
    12. int[] a= {1,32,98,12,90};
    13. Arrays.stream(a).forEach(s->System.out.println(s));
    14. }
    15. }

    (4)一些零散数据

    静态方法of可以=传递零散数据,也可以是一个数组,如果是基本数据类型数组,传递进去的是地址,引用数据类型则是值。

    1. package article;
    2. import java.util.*;
    3. import java.util.Collection;
    4. import java.util.Map.Entry;
    5. import java.util.*;
    6. import java.util.function.Consumer;
    7. import java.util.function.IntConsumer;
    8. import java.util.stream.Stream;
    9. import java.util.*;
    10. import java.util.*;
    11. public class first {
    12. public static void main(String[] args) {
    13. Stream.of("1",";").forEach(s->System.out.println(s));
    14. int[] a= {1,2,8};
    15. String[] b= {"klj",";;;"};
    16. Stream.of(a).forEach(s->System.out.println(s));
    17. Stream.of(b).forEach(s->System.out.println(s));
    18. }
    19. }

    三、Stream流中常用的API方法

    (1)中间方法

    修改stream流中的数据,但不会影响原来集合或者数组中的数据。这里建议使用链式编程。

    1. Streamfilter(Predicatesuper T>predicate) 过滤
    2. Streamlimit(long maxsize) 获取前几个元素
    3. Streamskip(long n) 跳过前几个元素
    4. Streamdistinct() 元素去重,以来hashcode和equals方法,自定义类时记得重写hashcode和equals
    5. staticStreamconcat(Stream a,Stream b) 合并a和b两个流为一个;流
    6. Streammap(Functionmapper) 转换流中的数据类型
    1. package article;
    2. import java.util.*;
    3. import java.util.Collection;
    4. import java.util.Map.Entry;
    5. import java.util.*;
    6. import java.util.function.Consumer;
    7. import java.util.function.IntConsumer;
    8. import java.util.function.Predicate;
    9. import java.util.stream.Stream;
    10. import java.util.*;
    11. import java.util.*;
    12. public class first {
    13. public static void main(String[] args) {
    14. ArrayList s=new ArrayList<>();
    15. Collections.addAll(s,"张三丰","周芷若","赵敏","张强","张无忌","张翠山","张亮","王二麻子","谢广坤");
    16. //第一个使用filter过滤,假如得到所有姓张的
    17. s.stream().filter(new Predicate() {
    18. @Override
    19. public boolean test(String t) {
    20. // 如果返回值是true,表示该数据留下
    21. if(t.startsWith("张")) {
    22. return true;
    23. }
    24. return false;
    25. }
    26. }).forEach(i->System.out.print(i+" "));
    27. System.out.println();
    28. //filter使用lambda表达式简写,我也推荐大家这样写,简单一点
    29. System.out.println("lambda写法:姓张并且长度=3----------------------");
    30. s.stream()
    31. .filter(i->i.startsWith("张"))
    32. .filter(i->i.length()==3)
    33. .forEach(i->System.out.print(i+" "));
    34. System.out.println();
    35. System.out.println("limit的使用");
    36. //第二个limit获取前几个元素
    37. System.out.println("获取stream中的前面两个元素:");
    38. s.stream().limit(2).forEach(i->System.out.print(i+" "));
    39. System.out.println();
    40. System.out.println("skip的使用");
    41. //第三个skip跳过前面几个元素
    42. System.out.println("跳过前面7个元素,也就是获得后面两个元素:");
    43. s.stream().skip(7).forEach(i->System.out.print(i+" "));
    44. System.out.println();
    45. System.out.println("distinct的使用:");
    46. //第四个distinct元素去重,依赖hashcode和equals(自定义对象记得重写)
    47. ArrayList list=new ArrayList<>();
    48. Collections.addAll(list, "张三丰","张三丰","周芷若","赵敏","张强","张无忌","张翠山","张亮","王二麻子","谢广坤");
    49. list.stream().distinct().forEach(i->System.out.print(i+" "));
    50. System.out.println();
    51. System.out.println("concat的使用");
    52. //第五个使用concat将a,b两个流合并成为一个流,注意这里两个流中的数据类型建议是一样的,不一样合并之后则是它们共同父类的数据类型
    53. ArrayList list1=new ArrayList<>();
    54. Collections.addAll(list1, "-=-=","[][][");
    55. Stream.concat(list1.stream(),s.stream()).forEach(i->System.out.print(i+" "));
    56. System.out.println();
    57. System.out.println("map的使用:");
    58. //第六个使用map转换流中的数据类型
    59. //比如来个需求现在想要下面集合中的年龄
    60. //这里注意一下map方法执行了以后,流上的数据就变成了整数,不在是之前的字符串了,所以后面的forEach打印出来的是数字
    61. ArrayList list2=new ArrayList<>();
    62. Collections.addAll(list2,"张无忌-15","周芷若-18","王柳-100","段誉-98");
    63. list2.stream().map(i->Integer.parseInt(i.split("-")[1]))
    64. .forEach(i->System.out.print(i+" "));
    65. System.out.println();
    66. }
    67. }

     

     

    (2)终结方法

    终结方法是什么呢,与中间方法有什么区别吗?没什么大的区别,都是方法,只不过终结方法使用过后就不能再对流进行操作了,它是对流做的最后一次操作了。

    1. void forEach() 遍历
    2. long count() 统计
    3. toArray() 收集流中的数据,放到数组中
    1. package article;
    2. import java.util.*;
    3. import java.util.Collection;
    4. import java.util.Map.Entry;
    5. import java.util.*;
    6. import java.util.function.Consumer;
    7. import java.util.function.IntConsumer;
    8. import java.util.function.IntFunction;
    9. import java.util.function.Predicate;
    10. import java.util.stream.Stream;
    11. import java.util.*;
    12. import java.util.*;
    13. public class first {
    14. public static void main(String[] args) {
    15. ArrayList s=new ArrayList<>();
    16. Collections.addAll(s,"张三丰","周芷若","赵敏","张强","张无忌","张翠山","张亮","王二麻子","谢广坤");
    17. String[] a=s.stream().toArray(new IntFunction() {
    18. //这里的IntFunction中的类型就是要转换成的数组类型
    19. //apply中的value是流中的数据个数,要和数组长度保持一致
    20. //apply的返回值是具体类型的数组
    21. @Override
    22. public String[] apply(int value) {
    23. // TODO 自动生成的方法存根
    24. return new String[value];
    25. }
    26. });
    27. System.out.println(Arrays.toString(a));
    28. //lambad表达式
    29. String[] b=s.stream().toArray((i)->{
    30. return new String[i];
    31. });
    32. System.out.println(Arrays.toString(b));
    33. }
    34. }

     

    (3)收集方法

    collect()                 收集流中的数据,放到集合(list,set,map)中

    注意啊,collect()也是终结方法使用了它之后后面就不能在使用其它什么了。

    1. package article;
    2. import java.util.*;
    3. import java.util.Collection;
    4. import java.util.Map.Entry;
    5. import java.util.*;
    6. import java.util.function.Consumer;
    7. import java.util.function.Function;
    8. import java.util.function.IntConsumer;
    9. import java.util.function.IntFunction;
    10. import java.util.function.Predicate;
    11. import java.util.stream.Collectors;
    12. import java.util.stream.Stream;
    13. import java.util.*;
    14. import java.util.*;
    15. public class first {
    16. public static void main(String[] args) {
    17. ArrayList s=new ArrayList<>();
    18. Collections.addAll(s,"张无忌-男-15","张无忌-男-15","周芷若-女-14","赵敏-女-13","张强-男-29","张三丰-男-100","张翠山-男-40","王五-男-66","谢逊-女-87");
    19. //第一个:收集到list集合中,这里的tolist底层是用ArrayList实现的
    20. //需求收集性别是男的,姓张的
    21. List list1=s.stream().filter(i->i.startsWith("张"))
    22. .filter(i->"男".equals(i.split("-")[1]))
    23. .collect(Collectors.toList());
    24. System.out.println(list1);
    25. //第二个:收集到Set集合中,与List集合不同的是Set集合不允许重复
    26. //这里的toSet方法底层是通过HashSet实现的
    27. Set list2=s.stream().filter(i->"男".equals(i.split("-")[1]))
    28. .filter(i->i.startsWith("张"))
    29. .collect(Collectors.toSet());
    30. System.out.println(list2);
    31. //第三个:收集到Map集合中,这里有一个注意点,键值一定不能重复,否则报错
    32. //我们要确定哪个是键哪个是值
    33. //这里我们将名字确定为键,年龄确定是值
    34. //
    35. ArrayList li=new ArrayList<>();
    36. Collections.addAll(li,"张无忌-男-15","周芷若-女-14","赵敏-女-13","张强-男-29","张三丰-男-100","张翠山-男-40","王五-男-66","谢逊-女-87");
    37. Map ma=li.stream().filter(i->i.startsWith("张"))
    38. .filter(i->"男".equals(i.split("-")[1]))
    39. .collect(Collectors.toMap(new Function(){
    40. //这里的toMap中的第一个参数是键的规则,第二个参数是值的规则
    41. //第一个参数的第一个参数是流的类型,第二个是转换的键的类型,第二个同样如此
    42. //返回值就是转换后的
    43. @Override
    44. public String apply(String t) {
    45. // TODO 自动生成的方法存根
    46. return t.split("-")[0];
    47. }
    48. }, new Function(){
    49. @Override
    50. public Integer apply(String t) {
    51. // TODO 自动生成的方法存根
    52. return Integer.parseInt(t.split("-")[2]);
    53. }
    54. }));
    55. System.out.println(ma);
    56. }
    57. }

    ​​​​​​​

     

  • 相关阅读:
    性价比高一点的蓝牙耳机有哪几款?高性价比蓝牙耳机推荐
    使用 OpenTelemetry 构建 .NET 应用可观测性(4):ASP.NET Core 应用中集成 OTel
    创建2个线程并执行(STL/Windows/Linux)
    基于JAVA+SpringMVC+MYSQL的网上人才招聘系统
    【数据处理必备Numpy~python】
    扫雷游戏分析实现(完整代码)
    c++对接CAT1400
    Java-基于SSM的图书书城管理系统
    虚拟DOM和真实DOM的区别和联系
    Git分支设计原则&分支常用操作练习
  • 原文地址:https://blog.csdn.net/gaoqiandr/article/details/128048088