书籍Java8 实战 笔记

第5章 使用流

本章内容
1.筛选、切片和匹配
2.查找、匹配和归约
3.使用数值范围等数值流
4.从多个源创建流
5.无限流

5.1 筛选和切片

用谓词筛选,筛选出各不相同的元素,忽略流中的头几个元素,或将流截短至指定长度。

5.1.1 用谓词筛选

就是filter方法,filter()里面的参数是一个布尔值函数,然后会返回为true的流。

5.1.2 筛选各异的元素

使用distinct()方法,就是会去除重复的数据

@Test
public void test(){
    List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
    numbers.stream()
            .filter(i -> i % 2 == 0)
            .distinct()
            .forEach(System.out::println);
}
结果: 2    4

5.1.3 截短流

@Test
public void test(){
    List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
    numbers.stream()
            .filter(i -> i % 2 == 0)
            .distinct()
            .limit(1)
            .forEach(System.out::println);
}
结果  2

5.1.4 跳过元素

skip(n),丢掉前n个元素的流,如果流中元素不足n个会返回一个空流。

@Test
public void test(){
    List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
    numbers.stream()
           .skip(1)
           .forEach(System.out::println);
}
2 1 3 3 2 4

5.2 映射

流支持map方法,它会接受一个函数作为参数,这个函数会应用到每个元素之上,然后会将其映射成一个新元素。

List<String> dishNames = menu.stream()
                             .map(Dish::getName)
                             .collect(Collectors.toList());

上面这个就是把Dish::getName方法传给了map,作用于所有的元素,但在map方法处理后输出的还是流是Stream

5.2.1 流的扁平化

例:如果将一个单词列表[“Hello”,“World”]想转化为[“H”,“e”,“l”, “o”,“W”,“r”,“d”]

public static void main(String[] args) {
    List<String> words = new ArrayList<>();
    words.add("Hello");
    words.add("World");
    List<String[]> list = words.stream()
            .map(word -> word.split(""))
            .distinct()
            .collect(Collectors.toList());
}
words.stream()  
     .map(item -> item.split(""))         Stream<String[]>  
     .distinct()                          Stream<String[]>  
     .collect(toList());                  List<String[]>
     
返回的是List<String[]>并非List<String>

但这么处理map返回的是Stream<String[ ]>类型(先是把每个单词转换成一个字母数组,然后把每个数组变成了一 个独立的流),而正确的处理应该是用Stream来表示一个流。
这里就可以使用flatMap来解决这个问题

List<String> uniqueCharacters = words.stream()  
                                     .map(w -> w.split(""))  
                                     .flatMap(Arrays::stream)   
                                     .distinct()  
                                     .collect(Collectors.toList());

flatMap(Arrays::stream) 会将单个流合并起来。

5.3 查找和匹配

另一个常见的数据处理套路是看看数据集中的某些元素是否匹配一个给定的属性。Stream API通过allMatch、anyMatch、noneMatch、findFirst和findAny方法提供了这样的工具。
allMatch: 流中所有元素是否能够匹配给定的谓词
anyMatch:流中是否有一个元素能够匹配给定的谓词
noneMatch:没有任何元素与给定的谓词匹配
findAny:返回当前流中的任意元素,可以与其他流操作结合使用。

Optional<Dish> dish = menu.stream()  
                          .filter(Dish::isVegetarian)  
                          .findAny();
补充一个无关的:
Optional.ofNullable(mp.selectList(queryWrapper)).orElse(new ArrayList<>(0));

5.4 规约

5.4.1 元素求和

int sum = numbers.stream().reduce(0 , (a,b)->a+b);

int sum = numbers.stream().reduce(0 , Integer::sum);

5.4.2 最大值和最小值

Optional<Integer> max = numbers.stream().reduce(Integer::max);  ```

```java
 Optional<Integer> min = numbers.stream().reduce(Integer::min); 

comparing补充

在这里插入图片描述

附录

// 获取结果中的排期id与用户id,其中key为排期id,value为该排期下所有用户id的集合
Map<Integer, List<String>> userAndScheduleMaps = scheduleStudentPage.getRecords().stream()
        .collect(Collectors.groupingBy(CourseScheduleStudentEntity::getCourseScheduleId,
                Collectors.mapping(CourseScheduleStudentEntity::getUserId, Collectors.toList())));

在这里插入图片描述
在这里插入图片描述

部分无关代码记录

Map map = new HashMap();  //定义Map集合对象
map.put("apple", "新鲜的苹果");  //向集合中添加对象
map.put("computer", "配置优良的计算机");
map.put("book", "堆积成山的图书");
Collection values = map.values();  //获取Map集合的value集合
for (Object object : values) {
    System.out.println("键值:" + object.toString());  //输出键值对象
}
键值:新鲜的苹果
键值:配置优良的计算机
键值:堆积成山的图书

过滤不为空
List<Object> departmentIds = staffInfoList.parallelStream()
        .map(FeishuStaffsEntity::getOpenDepartments)
        .distinct()
        .filter(Objects::nonNull)
        .collect(Collectors.toList());

LambdaQueryWrapper<EArticleAnchorEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
        .eq(EArticleAnchorEntity::getArticleId, articleId)
        .eq(EArticleAnchorEntity::getAnchor, articleAnchor);
EArticleAnchorEntity eArticleAnchorInfo = eArticleAnchorDao.getOne(queryWrapper,false);
Validator.notNull(eArticleAnchorInfo,"参数错误:未找到锚点记录");


private Map<String, CourseReportBo> getReportAndState(Page<CourseScheduleStudentEntity> scheduleStudentPage) {

        // 获取结果中的排期id与用户id,其中key为排期id,value为该排期下所有用户id的集合
        Map<Integer, List<String>> userAndScheduleMaps = scheduleStudentPage
                .getRecords()
                .stream()
                .collect(Collectors.groupingBy(CourseScheduleStudentEntity::getCourseScheduleId,
                        Collectors.mapping(CourseScheduleStudentEntity::getUserId, Collectors.toList())));

        // 获取用户report报告
        LambdaQueryWrapper<StatisticCourseSheduleStudentEntity> conds = new LambdaQueryWrapper<>();
        userAndScheduleMaps.entrySet().stream().forEach(userAndScheduleMap -> {
            conds.or(idEntity -> {
                idEntity.eq(StatisticCourseSheduleStudentEntity::getCourseScheduleId, userAndScheduleMap.getKey());
                idEntity.in(StatisticCourseSheduleStudentEntity::getUserId, userAndScheduleMap.getValue());
            });
        });
        List<StatisticCourseSheduleStudentEntity> entityResult = statisticCourseSheduleStudentDao.listByConds(conds);

        return entityResult.stream().filter(
                entity -> StringUtils.isNotBlank(entity.getReport()))
                .collect(Collectors.toMap(
                        entity -> entity.getCourseScheduleId() + ":" + entity.getUserId(),
                        entity -> JSONObject.parseObject(entity.getReport(), CourseReportBo.class)
                ));
    }


.sorted(Comparator.comparing(StudentExamRecordVo::getChapterName)
                        .thenComparing(StudentExamRecordVo::getSectionName)
                        .thenComparing(StudentExamRecordVo::getStartTime))
                .collect(Collectors.toList());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boy快快长大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值