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

2019-04-06  本文已影响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>>)


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}]}



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>>> 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}]}}


上一篇 下一篇

猜你喜欢

热点阅读