简聊JAVA8 特性之一:stream流操作

创建stream

    1、可以通过Collection集合提供的stream()和parallelStream();
    List list=new ArraysList<>();
    Stream stream1=list.stream();
    2、通过arrays中的静态方法Stream()获取数组流
    Person[] per = new Person[10];
    Stream stream= Arrays.stream(per );
    3、通过stream流的静态方法of()
    Stream a = Stream.of("a", "b");
    4、创建无线流
    //迭代
    Stream iterate = Stream.iterate(0, x -> x + 2);
    //生成
    Stream generate = Stream.generate(() -> Math.random());

Stream的相关操作

中间操作

1、筛选与切片
        filter -- 接受lambda,从流中排除某些元素
        limit -- 截断流,是元素不超过给定的数量,找到limit条数后就不会在进行其他操作了
        skip(n)--跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个则返回一个空值 与limit(n)互补
        distinct -- 筛选,通过流所生成元素的hashcode和equal去除重复的元素,如果是自己的定义的对象,需要重写hashcode和equals

List listPer = Arrays.asList(
                new Person("zs",16,170),
                new Person("ls",20,170),
                new Person("ww",5,170),
                new Person("zl",66,170),
                new Person("zl",66,170)
				);
			//外部迭代
			Iterator iterator = listPer.iterator();
			while(iterator.hasNext())
				System.out.println(iterator.next());
			//内部迭代:由stream API自己完成
			//中间操作 不会执行任何操作
			Stream personStream = listPer.stream().filter(
					e->{System.out.println("执行中间操作");
					return e.getAge() > 10;

			}).skip(2).limit(2).distinct();
			//终止操作 一次性执行完全部内容,即”惰性求值“
			personStream.forEach(System.out::println);

2、映射
     map --接受lambda将元素转换为其他形式或提取信息。接受一个函数作为参数,该函数会被应用到每一个元素上,并将其映射为一个新的元素。
     flatMap -- 接受一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有的流连城一个流

List list= Arrays.asList("a","b","c");
        list.stream().map(x->x.toUpperCase()).forEach(System.out::println);
		
		map和flatMap的区别
		Stream> streamStream = list.stream().map(test8::getStream);
		Stream characterStream = list.stream().flatMap(test8::getStream);

		
		public static Stream getStream(String  str){
			List list = new ArrayList<>();

			for (Character ch : str.toCharArray()) {
				list.add(ch);
			}
			return list.stream();
		}

3、排序
    sorted():自然排序(comparable排序 )
    sorted(Comparetor com):定制排序(comparetor排序) 

List list= Arrays.asList("z","b","c");
        list.stream().sorted().forEach(System.out::println);//结果是 b,c,z ,也就是按照字典顺序进行比较排序
		


		List listPer = Arrays.asList(
                new Person("zs",16,170),
                new Person("ls",20,170),
                new Person("ww",5,170),
                new Person("zl",66,170),
                new Person("zl",66,170)
        );
        listPer.stream().sorted((e1,e2)->{
            if (e1.getHeight()==e2.getHeight()){
                return -Integer.compare(e1.getAge(),e2.getAge());//不加 - 号表示使用从大到小,加-号表示从小到大
            }else{
                return e1.getName().compareTo(e2.getName());
            }}).forEach(System.out::println);
    }// 结果是:
				Person{name='ww', age=5, Height=170}
				Person{name='zs', age=16, Height=170}
				Person{name='ls', age=20, Height=170}
				Person{name='zl', age=66, Height=170}
				Person{name='zl', age=66, Height=170}

终止操作

1、查找与匹配
     allMatch -- 检查元素匹配所有元素
     anyMatch -- 检查是否至少匹配一个元素
     noneMathc -- 检查是否没有匹配所有元素(有匹配的元素,false:代表有匹配的元素,true代表没有匹配的元素)
     findFirst --返回第一个元素
     findAny -- 返回当前流中的任意元素
     count --    返回流中元素总数
     max --返回流中元素的最大值
     min -- 返回流中元素最小值

public static void main(String[] args) {
        List listPer = Arrays.asList(
                new Person("zs",16,170),
                new Person("ls",20,170),
                new Person("ww",5,170),
                new Person("zl",66,170),
                new Person("zl",67,171)
        );

        boolean b = listPer.stream().allMatch(e -> e.getHeight() == 170);  //true
		boolean zs = listPer.stream().anyMatch(e -> e.getName().equals("zs")); //true
		boolean ww = listPer.stream().noneMatch(e -> e.getName().equals("11"));//true
		Optional first = listPer.stream().findFirst(); //Optional[Person{name='zs', age=16, Height=170}]
        //optional是个容器,如果获取的第一个值为空,就会放到容器中,然后你需要通过orElse()进行另外赋值,如同if-else一样,不赋值依旧会出现异常
		//防止空指针异常,这也是java8的特性之一
        first.orElse(new Person("zs",16,170));//如果为空就默认新对象
		Optional any = listPer.stream().findAny();
		//findAny并不是随机地选一个,如果是数据较少,串行地情况下,一般会返回第一个结果,如果是并行的情况,那就不能确保是第一个。(Stream流是串行,parallelStream是并行的))
		//获取的是第一个值,此时stream是有顺序的,相当于一个list,把list中的数字按顺序去执行findany,找到第一个,所以是第一个值
		//如果此时用filter过滤一下把年龄大于20的留下,按照顺序获取然后一个一个执行findany(),新的流里面首先找到第一个,所以是第一个值
		
		long count = listPer.stream().count(); //5
        Optional max = listPer.stream().max((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
        Optional min = listPer.stream().min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));

2、归约

reduce(T identity,BinaryOperation)--可以将流中元素反复结合起来,得到一个值返回值是T

reduce(BinaryOperation)  --可以将流中元素反复结合起来,得到一个值返回值是Optional

	public static void main(String[] args) {
        List listPer = Arrays.asList(
                new Person("zs",16,170),
                new Person("ls",20,170),
                new Person("ww",5,170),
                new Person("zl",66,170)

        );
        List list = Arrays.g(1,2,3,4,5,6,7);
        //此种计算是,第一个是起始的操作值,后面是对每个元素的操作方法,第一次读取一个1,x=0,y=1 ,x+y=1
        //第二次读取一个2,x=1,y=2,x+y=3
        //第三次读取一个3,x=3,y=3,x+y=6
        //第四次读取一个4,x=6,y=4,x+y=10
        Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
        //计算年纪的总和
        //上面的返回值是interge是因为你给的起始值是interge类型,下面的返回值是optional因为是没有给起始值,只给运算规则,所以需要放到容器里
        Optional reduce1 = listPer.stream().map(Person::getAge).reduce(Integer::sum);

        System.out.println(reduce1.get());

3、收集

collect-- 将流转化为其他的形式。接收一个collect接口的实现,用于stream流中的元素汇总

//将对象person中的用户名收集成一个集合
	//Collections这个类里面有很多收集的方法,如tolist,toset
	List collect = listPer.stream().map(Person::getName).collect(Collectors.toList());
	//collections内部没有hash等方法
	Collection collect1 = listPer.stream().map(Person::getName).collect(Collectors.toCollection(HashSet::new));
	//收集总数
	listPer.stream().collect(Collections.count());
	//获取年纪的平均值
	Double collect2 = listPer.stream().collect(Collectors.averagingInt(Person::getAge));
	//总和
	IntSummaryStatistics collect23 = listPer.stream().collect(Collectors.summarizingInt(Person::getAge));
	//获取员工年纪最大的员工最大的信息
	 Optional collect3 = listPer.stream().collect(Collectors.maxBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));
	//获取员工最小年纪
	Optional collect3 = listPer.stream().collect(Collectors.minBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));
	Optional collect4 = listPer.stream().map(Person::getAge).collect(Collectors.minBy(Integer::compare));
    System.out.println(collect4.get());
	//分组
	Map> collect5 = listPer.stream().collect(Collectors.groupingBy(Person::getAge));
	#结果是:
	#{16=[Person{name='zs', age=16, Height=170}], 
	#66=[Person{name='zl', age=66, Height=170}], 
	#20=[Person{name='ls', age=20, Height=170}], 
	#5=[Person{name='ww', age=5, Height=170}]}
	//多级分组,下面是先进行年纪分组,在进行身高分组
	Map>> collect6 = listPer.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy(e -> {
            if (e.getHeight() > 170) {
                return "高个";
            } else {
                return "矮个";
            }
        })));
	#{16={矮个=[Person{name='zs', age=16, Height=170}]}, 
	#66={矮个=[Person{name='zl', age=66, Height=170}]}, 
	#20={矮个=[Person{name='ls', age=20, Height=170}]}, 
	#5={矮个=[Person{name='ww', age=5, Height=170}]}}

	//分区,分为true和false区
	Map> collect7 = listPer.stream().collect(Collectors.partitioningBy(e -> e.getAge() > 20));
	#{false=[Person{name='zs', age=16, Height=170}, Person{name='ls', age=20, Height=170}, Person{name='ww', age=5, Height=170}], true=[Person{name='zl', age=66, Height=170}]}
	//other
	IntSummaryStatistics collect8 = listPer.stream().collect(Collectors.summarizingInt(Person::getAge));
        double average = collect8.getAverage();
        long count = collect8.getCount();
        long sum = collect8.getSum();
	//链接
	String collect9 = listPer.stream().map(Person::getName).collect(Collectors.joining("-"));
	#结果是:zs-ls-ww-zl
	String collect9 = listPer.stream().map(Person::getName).collect(Collectors.joining("-","===","==="));
	#结果是:===zs-ls-ww-zl===

ifPresent用法

ifPresent 用于对过滤数据(也可以是流返回的option进)进行判空,如果不未空则为true,空则为false

从源码我们就能看出来

简聊JAVA8 特性之一:stream流操作_第1张图片

//判断是否为空
Optional dict = orgGrade.stream().filter(org -> org.getValue().equals(String.valueOf(grade))).findFirst();
// 判断是否有值
if(dict.isPresent())//true为真,false为假
    System.out.print(dict.getValue())

ifPresent 如果经过过滤条件后,有数据的话就可以进行修改。

 Optional firstA= AList.stream() 
                          .filter(a -> "小明".equals(a.getUserName())) 
                          .findFirst()
                          .ifPresent(a -> {
                              a.setUserName("明明");
                          })

以上边是我整理的,如有异议,请回复

你可能感兴趣的:(java8)