Java Stream API 和 自定义注解 笔记

一、Stream

1、Stream概述

一组用来处理数组、集合的api
java 8之所以引入函数式编程有两个主要原因

  • 代码简洁,意图明确,stream接口可以让你告别for循环
  • 多核友好,并行程序编写变得极为简单,只需调用一下parallel()方法

stream特性

  • 不是数据结构,没有内部存储
  • 不支持索引访问
  • 延迟计算
  • 支持并行
  • 很容易生成数组或集合(List,Set)
  • 支持过滤,查找,转换,汇总,聚合等操作

stream运行机制

  • 分为源source,中间操作,终止操作
  • 流的源可以是一个数组、一个集合,一个生成器方法,一个I/O通道等等。
  • 一个流可以有零个和或者多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作
  • Stream只有遇到终止操作,它的源才开始执行遍历操作

Stream的创建

  • 通过数组
  • 通过集合
  • 通过Stream.generate方法
  • 通过Stream.iterate方法
  • 其他API创建

中间操作

  • 过滤 filter
  • 去重 distinct
  • 排序 sorted
  • 截取 limit、skip
  • 转换 map/flatMap
  • 其他 peek

终止操作

  • 循环 forEach
  • 计算 min、max、count、average
  • 匹配 anyMatch、allMatch、noneMatch、findFirst、findAny
  • 汇聚 reduce
  • 收集器 toArray collect

2、创建Stream对象

在这里插入图片描述

package com.company;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Main{

    //通过数组生成
    static void gen1(){
        Integer num[] = {1,2,3,4,5};
        //Stream类中有静态方法of(T t)返回包含单个元素的顺序Stream,of(T…values)的流返回其元素为指定值的顺序有序流
        Stream<Integer> num1 = Stream.of(num);
        num1.forEach(System.out::print);//System.out::print 实例方法引用,引用System.out类的print方法
    }
    //通过集合生成
    static void gen2(){
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        Stream<List<Integer>> integers1 = Stream.of(integers);
        integers1.forEach(System.out::print);
    }
    //通过generate
    static void gen3(){
        //流generate(Supplier s)返回无限顺序无序流,其中每个元素由提供的供应商生成。这适用于生成恒定流,随机元素流等。其中Supplier是函数式接口,表示一个输出
//        Supplier supplier = ()->1;  只能有一个输出,不能有输入
        Stream<Integer> generate = Stream.generate(() -> (Integer)new Random().nextInt(10));
        //limit(Integer i) 规定流生成的个数,因为generate是无限流。如果不规定会一直生产下去
        generate.limit(10).forEach((e)->System.out.print(e+" "));
    }
    //通过iterator
    static void gen4(){
        //Stream.iterate(常量,一输入一输出函数式接口);通过迭代函数,生成一个有序无限的数据流。(由于是无限流,一般都是配合limit来使用)
        Stream<Integer> iterate = Stream.iterate(1, (x) -> x + 1);
        iterate.limit(10).forEach((e)-> System.out.print(e+" "));
    }
    //其他方法
    static void gen5(){
        String abcdef = "abcdef";
        IntStream intStream = abcdef.chars();

        intStream.forEach(System.out::print);
    }
    public static void main(String[] args) {
        gen1();
        System.out.println();
        gen2();
        System.out.println();
        gen3();
        System.out.println();
        gen4();
        System.out.println();
        gen5();
    }
}

3、中间操作和终止操作

在这里插入图片描述

package com.company;

import org.w3c.dom.ls.LSOutput;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main{

    public static void main(String[] args) {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4,5,6,7,8,9,10);//创建一个包含10个元素的集合

        //List.stream()方法,用于将可迭代对象,转换为Stream流对象
        //filter()方法是一个过滤方法,用于返回结果为true的对象,比如下面x>5的数返回为true就表示这个x是满足条件的元素,会添加到Stream流中
        Stream<Integer> integerStream = integers.stream().filter((x) -> {
            return x > 5;//如果条件为false,那么当前元素会被过滤掉,如果为true,当前元素会被留下放在流中
        });
        integerStream.forEach((e)-> System.out.print(e+" "));
        //mapToInt()返回一个IntStream,其中包括将给定函数应用于此流的元素的结果。IntStream中有一些方法,比如sum就是求和方法
        int sum = integers.stream().mapToInt(x -> x).sum();
        System.out.println("\n"+sum);

        //去重,distinct方法用于去重
        System.out.println(
                Arrays.asList(1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4).stream().distinct().collect(Collectors.toList()).toString()
        );

        //max 取最大值,但是返回OptionalInt对象,其中有get方法可以取值
        OptionalInt max = integers.stream().mapToInt(x -> x).max();
        System.out.println(max.getAsInt());

        //我喜欢的取最大值和最小值方法,sorted()排序方法默认自然排序,就是从小到大,需要从大到小需要自己写逻辑,findFitst()返回第一个元素
        Optional<Integer> min = integers.stream().sorted().findFirst();
        //(a,b) -> b - a,a和b是依次遍历的值,b-a表示如果当前b的值-a的值,是正数,说明b这个值大,放前面
        Optional<Integer> Max = integers.stream().sorted((a, b) -> b - a).findAny();

        System.out.println(min.get()+"------------"+Max.get());

        /**将集合中元素做某些操作,然后重新返回一个集合
         * collect方法,将stream对象转换为Collector接口,此接口的toList方法可以将序列转换为List集合
         * */
        List<Integer> collect = integers.stream().sorted((a,b)->b-a).collect(Collectors.toList());
        System.out.println(collect.toString());

        //获取20-30集合的三种方式
        Stream.iterate(20,x->x+1).limit(11).forEach(e-> System.out.print(e+" "));
        System.out.println();
        //skip方法用于跳过指定次数的生产
        Stream.iterate(1,x->x+1).limit(30).skip(19).forEach(e -> System.out.print(e+" "));
        System.out.println();
        //下面这种方法其实多余,就是告诉大家,跳过后还可以用limit规定多少个
        Stream.iterate(1,x->x+1).limit(100).skip(19).limit(11).forEach(e -> System.out.print(e+" "));

        
    }
}

二、自定义注解

1、注解概述

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

package com.company;

import java.lang.annotation.*;

public class Main{
    @MyAnnotation(int1 = "a",value = "a")
    public static void main(String[] args) {

    }
}

/**
 * 使用@interface定义一个注解
 *
 * @Taarget注解 标注当前自定义注解的作用范围,只有一个value属性,
 *                  其中ElementType.METHOD,表示此注解可以用在方法上,
 *                  ElementType.TYPE表示可以用在类上
 *                  还有其它的请参考源码的注释,都有解释
 * @Retention 标注当前自定义注解在什么环境可以被识别
 *                  RetentionPolicy.SOURCE 表示在源码级别可以被识别
 *                  RetentionPolicy.CLASS 表示在类的环境下
 *                  RetentionPolicy.RUNTIME 表示在运行时
 */

@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
@Documented //标注当前注解在生成java文档时,包含在文档中,就是javadoc中
@Inherited //标注当前注解可以被子类继承
@interface MyAnnotation{
    /**
     * 这里定义的不是方法了,而是注解的参数值也就是注解后面括号中需要传递的参数
     * 默认是value,如果是value可以省略
     */
    String[] value();//数组参数,使用时,如果只有一个值,可以直接写,如果有多个参数需要value = {"1","2"}
    String int1(); //非数组参数,使用时,直接赋值即可

    String int2() default "10";//包含默认值,如果不指定默认值,那么使用注解时,必须为参数赋值,加上default后,可以不赋值,自动使用默认值
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

殷丿grd_志鹏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值