java8 流式编程详细讲解(一)之 Stream、Collector

Java 8 中引入了新特性,流式编程思想,为其增加了有一个新的亮点!因为流的一个核心好处是,使得代码程序更加精简并且更易理解。在某些数情况下,将对象存储在数组、集合中是为了处理他们,而现在你可以把编程的主要焦点从其转移到了流上,使得java更具有吸引力。下面看一些实例:

1、随机展示 1 至 50 之间不重复的整数并进行排序。实际上,你的关注点首先是创建一个有序集合。使用流式编程,你就可以简单的这样做:

public static void main(String[] args) {
    new Random(47)
            .ints(1, 50)
            .distinct()
            .limit(7)
            .sorted()
            .forEach(System.out::println);
}

有Java基础的伙伴们看到后可能会心一笑!这么简洁啊。

首先,我们给 Random 对象一个种子   ints() 方法产生一个流并且 ints() 方法产生一个整数流。 distinct() 来获取它们的非重复值,然后使用 limit() 方法获取前 7 个元素。sorted() 方法排序。最终使用 forEach() 方法遍历输出,它根据传递给它的函数对每个流对象执行操作。我们传递了一个可以在控制台显示每个元素的方法引用。System.out::println 相当于System.out.println (),这是Java函数式编程思想的一种体现,以后会详细解读Java函数式编程。

2、每个集合可以通过调用 stream() 方法来产生一个流

public static void main(String[] args) {
    Set w = new HashSet<>(Arrays.asList("You are a good student!".split(" ")));
    w.stream().map(x -> x + " ").forEach(System.out::print);
    System.out.println("...........");

    Map m = new HashMap<>();
    m.put("a", 9.9);
    m.put("b", 26.8);
    m.put("c", 1.0);
    m.entrySet().stream().map(e -> e.getKey() + ": " + e.getValue()).forEach(System.out::println);
}
输出结果:

a are student! good You ...........
a: 9.9
b: 26.8
c: 1.0

所有集合  如 上w、  m  都有的 stream()方法,然后 map() 会获取流中的所有元素,并且对流中元素进行操作从而产生新的元素,并将其传递到流中。通过map() 会获取对象并产生新的对象,但是这里有特殊版本的方法用于数值类型的流。例如,mapToInt() 方法将一个对象流(objects stream)转换成为包含整形数字的 IntStream。同样,针对 String 和 Double 也有类似名字的操作。

为了从 Map 集合中产生流数据,我们首先调用 entrySet() 去产生一个对象流,每个对象都包含一个 key 键以及与其相关联的 value 值。然后调用 getKey() 和 getValue() 将其分开遍历。

3、使用 Collectors 类来收集元素到特定的结果集合中 如:tocollect() 、.toCollection()、.toMap()等

public static void main(String[] args) {
    List fileToWords = new ArrayList<>();
    fileToWords.add("nandao");
    fileToWords.add("nandao");
    fileToWords.add("ytao");
    fileToWords.add("mage");
    ArrayList words =
            fileToWords.stream()
                    .collect(ArrayList::new,
                            ArrayList::add,
                            ArrayList::addAll);
    words.stream()
            .filter(s -> s.equals("nandao")).collect(Collectors.toList())
            .forEach(System.out::println);
}
输出结果:

nandao
nandao

这里有两个重要的语法:

A、collect(Collector):使用 Collector 来累计流元素到结果集合中,如:collect(Collectors.toList())  源码如下:

B、collect(Supplier, BiConsumer, BiConsumer):同上,但是 Supplier 创建了一个新的结果集合,第一个 BiConsumer是将下一个元素包含在结果中的函数,而第二个 BiConsumer 是用于将两个值组合起来,源码如下:

public static 
    Collector> toList() {
        return new CollectorImpl<>((Supplier>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

4、从一个list对象里取出对象的某一个参数,返回list:

List userList = param.getUserList();
 
List userIdList = userList.stream().map(UserInfo::getId).collect(Collectors.toList());

5、list中对象取出一个参数作为key,对象作为value 或者其他的一个属性作为value。

List userList = param.getUserList();
 


Map userIdMap = userList.stream().collect(Collectors.toMap(UserInfo::getId, t -> t));

Map userIdMap = userList.stream().collect(Collectors.toMap(UserInfo::getId, UserInfo::getName));

注意:要求list对象里有不能重复的key,否则转化时报错!

6、 list中生成map分组,相同key的对象放在一个集合里

List userList = param.getUserList();
 
 
Map> userNoMap = userList.stream().collect(Collectors.groupingBy(UserInfo::getNo));

大家可以细看一下 ,两个方法的核心是一样的。从今以后平时写代码的时候就可以替换for 、forEach循环了,让自己的代码更加简洁、高效、易于理解。(这就是流式编程比声明式编程好的地方!)

7、循环操作:

                deleteList.forEach(entity -> {entity.setOil(compareBigDecimal);});

理论参考

理论参考2

使用参考

使用参考2

使用参考3

今天先讲到这里,小伙伴有哪里不明白的地方,可以随时留言!

你可能感兴趣的:(java相关,java,servlet,jvm)