美文网首页
Java8新特性Stream学习(二)尖刀利器

Java8新特性Stream学习(二)尖刀利器

作者: 惜鱼 | 来源:发表于2019-04-06 11:17 被阅读0次

距离上一篇的文章发布已经过了大半年,由于各种原因没有保持及时的更新,实在是惭愧,这里一节将继续讲解JAVA Stream的使用,合理使用Steam可以提升我们的开发效率同时还能简化代码。

image

Stream默认提供了很多的方法,基本上可以满足我们平时的使用,如果有特殊需要也可以自己扩展。

1.字符串连接

1.在没有使用Stream时,我们通常拼接字符是这样的


List<String> values = Arrays.asList("Tom", "Jack", "David", "Rose");

StringBuilder builder = new StringBuilder();
for (String s : values) {
    builder.append(s);
}

这时候看起来还没有什么,如果我需要在每个字符串中间加一个分割符,什么之类,然后就是这样了


StringBuilder builder = new StringBuilder();

for (String s : values) {
    builder.append(s).append("-");
}
// 替换1
String result = builder.substring(0, builder.length() - 1);
// 替换2
builder.delete(builder.length() - 1, builder.length());

out:
Tom-Jack-David-Rose

这时候如果再进行一些复杂的操作时,可能就不是怎么简单了,我再看看使用Stream的代码


List<String> values = Arrays.asList("Tom", "Jack", "David", "Rose");
// 一行代码就可以实现
String simple = values.stream().collect(Collectors.joining("-"));

// 如果我们需要在开始或者结尾加一点东西的时候就是这样
String complex = values.stream().collect(Collectors.joining("-", "[", "]"));

out:

Tom-Jack-David-Rose
[Tom,Jack,David,Rose]

经过源码分析后,joining() 方法的实现也是利用StringBuilder来实现的,只不过是JAVA提供的语法糖,以下提供部分源码


public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
    return joining(delimiter, "", "");
}

public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
                                                             CharSequence prefix,
                                                             CharSequence suffix) {
    return new CollectorImpl<>(
            () -> new StringJoiner(delimiter, prefix, suffix),
            StringJoiner::add, StringJoiner::merge, // 这里的add就是使用StringBuilder中的append来实现的
            StringJoiner::toString, CH_NOID);
}

public StringJoiner add(CharSequence newElement) {
    prepareBuilder().append(newElement);
    return this;
}

private StringBuilder prepareBuilder() {
    if (value != null) {
        value.append(delimiter);
    } else {
        value = new StringBuilder().append(prefix);
    }
    return value;
}

2.数据分组

现在的需求如下,从数据库中查找到一个班级的学生(List集合),需要按照性别分组,然后放入Map集合返回(结构:Map<String, List<Student>>)

  • 在没有使用Stream之前,我们通常的写法

StudentService studentService = new StudentService();
List<Student> students = studentService.getList();

Map<String, List<Student>> groupStudent = new HashMap<>(5);
List<Student> boy = new ArrayList<>(16);
List<Student> girl = new ArrayList<>(16);
for (Student s : students) {
    if (s.isMan()) {
        boy.add(s);
        continue;
    }
    girl.add(s);
}
groupStudent.put("body", boy);
groupStudent.put("girl", girl);

out:
{body=[Student{name='小明', age=18, gender='男', className='高三一班', score=null, classFee=50.0}, Student{name='小军', age=16, gender='男', className='高三二班', score=null, classFee=50.0}], girl=[Student{name='小丽', age=17, gender='女', className='高三一班', score=null, classFee=50.0}, Student{name='小丽', age=18, gender='女', className='高三二班', score=null, classFee=100.0}]}


  • 使用Stream的处理方法

Map<String, List<Student>> result = students.stream()
                .collect(Collectors.groupingBy(Student::getGender, Collectors.toList()));

out:

{女=[Student{name='小丽', age=17, gender='女', className='高三一班', score=null, classFee=50.0}, Student{name='小丽', age=18, gender='女', className='高三二班', score=null, classFee=100.0}], 男=[Student{name='小明', age=18, gender='男', className='高三一班', score=null, classFee=50.0}, Student{name='小军', age=16, gender='男', className='高三二班', score=null, classFee=50.0}]}

  • 如果这时候我们再加一个需求就是先按照年级分组,然后在按照性别分组(结构:Map<String, Map<String, List<Student>>>),这时候,对于这种需求你是不是就觉得有些不爽了。这里我就不展示传统的写法了,相信你已经想到了

  • 使用Stream实现


Map<String, Map<String, List<Student>>> advanced = students.stream()
                .collect(Collectors.groupingBy(Student::getClassName,
                        Collectors.groupingBy(Student::getGender, Collectors.toList())));

out:
{高三二班={女=[Student{name='小丽', age=18, gender='女', className='高三二班', score=null, classFee=100.0}], 男=[Student{name='小军', age=16, gender='男', className='高三二班', score=null, classFee=50.0}]}, 高三一班={女=[Student{name='小丽', age=17, gender='女', className='高三一班', score=null, classFee=50.0}], 男=[Student{name='小明', age=18, gender='男', className='高三一班', score=null, classFee=50.0}]}}


相关文章

  • Java8新特性Stream学习(二)尖刀利器

    距离上一篇的文章发布已经过了大半年,由于各种原因没有保持及时的更新,实在是惭愧,这里一节将继续讲解JAVA Str...

  • Stream流

    Stream流 java8新特性 Stream定义 A sequence of elements supporti...

  • JAVA8新特性:Stream与Lambda表达式

    一、Stream学习 在学习lambda表达式之前,我们需要先了解Stream这个java8的新特性。 Strea...

  • Stream API

    Stream 声明:java8新特性系列为个人学习笔记,参考地址点击这里,侵删!! Stream API Java...

  • java中List去重

    方法一、使用Set集合特性 方法二、使用java8 stream api

  • java 8 stream 流详细教程

    1 基本特性 Java8的API中添加了一个新的特性: 流,即stream。stream是将数组或者集合的元素视为...

  • Java8新特性系列(流性能)

    上期介绍了Java8中Stream的新特性,本期我们将测试下stream与parallelStream的性能以及应...

  • java8新特性

    java8新特性 原创者:文思 一、特性简介 速度更快 代码更少,增加了Lambda 强大的Stream API ...

  • Java8 新特性(二)- Stream

    Stream 用来处理集合数据的,通过 stream 操作可以实现 SQL 的拥有的大部分查询功能 Java8 A...

  • JAVA8新特性—Stream(二)

    一个流操作的示例 stream() 获取当前小物件的 source,filter 和 mapToInt 为 int...

网友评论

      本文标题:Java8新特性Stream学习(二)尖刀利器

      本文链接:https://www.haomeiwen.com/subject/jqcriqtx.html