Stream流的常用方法

1、快速创建List

public class User {
    public User(String name, String age, int height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }
    private String name;
    private String age;
    private int height;
    // setter、getter方法我就不写了
}
// 创建三个user
User user1 = new User("111", "18", 180);
User user2 = new User("222", "18", 175);
User user3 = new User("333", "19", 170);

(1)new一个list,一个一个添加

List<User> userList = new ArrayList<>();
userList.add(user1);
userList.add(user2);
userList.add(user3);

(2)、Stream流:创建动态list,可以添加元素

// stream流,创建的是动态数组,可以添加元素
List<User> userList = Stream.of(user1, user2, user3).collect(Collectors.toList());

(3)、如果创建一个固定长度的list,可以使用Arrays.asList(…args)直接返回一个list

本质是将一个数组转成list,数组的大小是固定的,所以此list不能添加元素,
如果调用add方法增加新的元素,会报异常:java.lang.UnsupportedOperationException
当元素是固定时,可以采用这个;

// 本质是将一个数组转成list,数组的大小是固定的,所以此list不能添加元素
// 如果调用add方法增加新的元素,会报异常:java.lang.UnsupportedOperationException
List<String> s = Arrays.asList("1","2","3") 

2、取对象的某一列:

拿上面userList举例,我取出list中所有user的name属性放到一个新的list中:

(1)、遍历

// 遍历
List<String> userNameList = new ArrayList<>();
for (User user : userList) {
    userNameList.add(user.getName());
}

(2)、Stream流:map

// Stream流
List<String> userNameList = userList.stream().map(User::getName).collect(Collectors.toList());

3、过滤,或者说是根据一个判断条件筛选出目标对象

还拿上面的userList,比如我要筛选出userList中name不为空的user

(1)、遍历加 if

List<User> newUserList = new ArrayList<>();
// if判断
for (User user : userList) {
    if(user.getName() != null) {
        newUserList.add(user); 
    }
}

(2)、Stream流:filter

// 获取userName不为空的user的List
List<User> userList = userList.stream().filter(user-> user.getName() != null).collect(Collectors.toList());

4、分组

把userList中的user根据年龄分组:

(1)、遍历加 if

Map<String, List<User>> map = new HashMap<>();
// if判断
   for (User user : userList) {
      if (map.get(user.getAge()) == null) {
         map.put(user.getAge(), new ArrayList());
      }
    map.get(user.getAge()).add(user);
   }

(2)、Stream流:groupingBy

   Map<String, List<User>> map =userList.stream().collect( Collectors.groupingBy(User::getAge, Collectors.toList()));

5、求和

(1)、int、double、long

求和的普通遍历方式跟上面差不多,就不举例了

// int、double、long:
   double max = userList.stream().mapToDouble(User::getHeight).sum();

6、Map、List互转

(1)、list转map:

a、遍历:

    Map<String, User> userMap = new Map<>();
    for (User user : userList) {
        userMap.put(user.getName(), user);
    }

b、stream流:

用Collectors的toMap方法转换List,一般会遇到两个问题。
(1)转换map,key重复问题;
代码中使用(key1,key2)->key2表达式可以解决此类问题,如果出现重复的key就使用key2覆盖前面的key1,也可以定义成(key1,key2)->key1,保留key1,根据自己的业务场景来调整。
(2)空指针异常,即转为map的value是null。这个可以用filter过滤;

   Map<String, User> userMap= userList.stream().collect(Collectors.toMap(User::getName, Function.identity(),(key1, key2)->key2));

(2)、map转list:

a、遍历:

    List<User> userList = new List<>();
    for (String userName : userMap.keySet()) {
        userList.add(userMap.get(userName));
    }

b、stream流:

   List<User> userList = userMap.entrySet().stream().map(e ->e.getValue()).collect(Collectors.toList());

7、做判断

(1)、anyMatch():

判断的条件里,任意一个元素成功,返回true;
比如上面的userlList,我想判断是否有height > 175的:

   userList.stream().anyMatch(user -> user.getHeight() > 175);

(2)、allMatch():

allMatch:判断条件里的元素,所有的都是,返回true;
比如上面的userlList,我想判断是否全部height > 175的:

   userList.stream().allMatch(user -> user.getHeight() > 175);

(3)、noneMatch():

与allMatch相反,判断条件里的元素,所有的都不是,返回true

   userList.stream().noneMatch(user -> user.getHeight() > 175);

(4)、求取目标和:

   userList.stream().filter(user -> user.getHeight() > 175).count();

8、合并List

(1)、合并多个一维List:

   List<Integer> list1 = Arrays.asList(1, 2, 3);
   List<Integer> list2 = Arrays.asList(4, 5, 6);
   List<Integer> list3 = Arrays.asList(7, 8, 9);
   List<Integer> mergedList = Stream.of(list1, list2, list3).flatMap(Collection::stream).collect(Collectors.toList());
   System.out.println(mergedList);// [1, 2, 3, 4, 5, 6, 7, 8, 9]

(2)、合并嵌套List:

   List<String> list1 = Arrays.asList("张三", "李四", "王二麻子");
   List<String> list2 = Arrays.asList("111", "222", "333");
   // 合并前
   List<List<String>> lists = Arrays.asList(list1, list2);
   System.out.println(lists);
   
   // 合并后
   List<String> mergedList = lists.stream().flatMap(Collection::stream).collect(Collectors.toList());
   System.out.println(mergedList);

9、分页

   Map<String,Object> map = Maps.newHashMap();
   List list = new ArrayList();
   //list -> 当前页所有数据
   map.put("list",list.stream().skip((long) (pageNo - 1) * pageSize).limit(pageSize).collect(Collectors.toList()));
   //count -> 记录总条数
   map.put("count",list.size());

10、limit方法

limit 方法可以对流进行截取,只取用前n个。方法签名:
Stream<T> limit(long maxSize);
参数是一个long型,如果集合当前长度大于参数则进行截取。否则不进行操作。基本使用:

   @Test
   public void testLimit() {
   List<String> one = new ArrayList<>();
      Collections.addAll(one, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");
      one.stream().limit(3).forEach(System.out::println);
   } 

11、skip方法

如果希望跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流:
Stream<T> skip(long n);
如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。基本使用:

   @Test
   public void testSkip() {
      List<String> one = new ArrayList<>();
      Collections.addAll(one, "迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子");
      one.stream().skip(2).forEach(System.out::println);
   } 

12、map方法

如果需要将流中的元素映射到另一个流中,可以使用 map 方法。方法签名:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
该接口需要一个 Function 函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。
Stream流中的 map 方法基本使用的代码如:

   @Test
   public void testMap() {
      Stream<String> original = Stream.of("11", "22", "33");
      Stream<Integer> result = original.map(Integer::parseInt);
      result.forEach(s -> System.out.println(s + 10));
   } 
   ~~~~~~~~~~~~
   public class demoStream_map {
      public static void main(String[] args) {
          //获取一个String类型的stream流
          Stream<String>stream = Stream.of("1","2","3","4");
          //使用map方法,把字符串类型的整数,转换(映射)为Integer类型的整数
          Stream<Integer> stream1 = stream.map((String s) -> {
              return Integer.parseInt(s);
          });
          stream1.forEach((i)-> System.out.println(i));
      }
   }

这段代码中, map 方法的参数通过方法引用,将字符串类型转换成为了int类型(并自动装箱为 Integer 类对象)。

13、concat方法合并流

concat:用于把流组合到一起
如果有两个流,希望合并成为一个流,可以使用Stream接口的静态方法concat

   public class demoStream_concat {
      public static void main(String[] args) {
          Stream<String> stream = Stream.of("张三", "李四", "王五", "赵六", "冯老七");
          String[] arr= {"QWQ", "ERE", "TYT", "UIU", "OIO"};
          Stream<String> stream1 = Stream.of(arr);
          //合并
          Stream<String> stream2 = Stream.concat(stream, stream1);
          stream2.forEach((name)-> System.out.print(name+" "));
      }
   }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容