JAVA实训第三天

目录

方法引用

示例

接口

测试类

Stream

​编辑 Stream 的操作三个步骤

 创建 Stream 的 4 种方法

 常见Stream接口的继承关系

Stream的中间操作

 中间操作常用方法

 Stream的终止操作

 Stream的终止操作-collect()

 示例代码演示

 作业


方法引用

        在Lamda新特性的支持下,JAVA8中可以使用lamda表达式来创建匿名方法。然而,有时候我们仅仅是需要调用一个已存在的方法(如java中已经定义好的方法),在这时候java8新特性“方法引用”将会进一步简化操作(注意:需要有Lamda的支持)。

方法引用的四种形式:
引用静态方法 --> 类名称 ::static 方法名称;
引用某个对象的实例的普通方法 --> 实例化对象 :: 普通方法;
引用 特定类型 任意对象 的实例方法 --> 特定类 :: 普通方法;
引用构造方法 --> 类名称 ::new

定义一个方法获取供给型接口类型的参数,调用 get 方法获取返回对象,并执行普通方法

 

 

示例

接口

package part4;

/**
 * @date : 2022/11/23 9:36
 */
@FunctionalInterface
public interface PersonInterface {
  public static  final   String name = "tidy";
  public static  final   Integer age =18;


  public void methodA();



}

package part4;

/**
 * @date : 2022/11/23 9:31
 */
public   class Person {

    String name;
    Integer age;

    public static int   method1() {
        System.out.println("static静态方法...");
        return 0;
    }

    public static int   method2(int a) {
        System.out.println("static静态方法..."+a);
        return 0;
    }



    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }


    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类

package part4;


import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;


/**
 * @date : 2022/11/23 9:29
 */
public class MethodReferenceDemo {

    public static void main(String[] args) {
     /*   方法引用的四种形式:
        引用静态方法-->类名称::static 方法名称;
        引用某个对象的实例的普通方法-->实例化对象::普通方法;
        引用特定类型的任意对象的实例方法-->特定类::普通方法;
        引用构造方法-->类名称::new
*/

//        1)引用构造方法-->类名称::new
        /*Person person = new Person();
        System.out.println(person);*/
//        注意事项1:方法引用 前提要使用lambda表达式--》功能性函数
//        Person person = Person::new;

//        注意事项2:接口中没有构造方法  调用不成
//        PersonInterface personInterface =  PersonInterface::new;

//        借助于供给型接口 实例化对象
        Supplier<Person> supplier = Person::new;
        Person person = supplier.get();
        System.out.println(person);


//        2) 引用静态方法-->类名称::static 方法名称;
        Supplier<Integer> method1 = Person::method1;
        Integer result = method1.get();
        System.out.println("result:"+result);

        System.out.println("==================");
//        调用静态方法时:选定和这个静态方法相匹配的功能性函数(是否匹配:是否有参数 是否有返回值--》使用哪个功能性函数)
        Function<Integer,Integer> function = Person::method2;
        Integer apply = function.apply(66);
        System.out.println("applay:"+apply);

        System.out.println("==================");
//        3)引用某个对象的实例的普通方法-->实例化对象::普通方法;
        Person person1 = new Person("tidy",18);
        Supplier<String> stringSupplier =person1::getName;
        String name = stringSupplier.get();
        System.out.println("name:"+name);


//        4)引用特定类型的任意对象的实例方法-->特定类::普通方法;
//        String equals方法  比较两个字符串是否相等  2个字符串
//        BiFunction
        BiFunction<String,String,Boolean> biFunction = String::equals;
        Boolean resultFlg = biFunction.apply("hello", "hello");
        System.out.println("resultFlg:"+resultFlg);

        System.out.println("6666666666666666666:");
        List<Integer> list = new ArrayList();
        list.add(10);
        list.add(30);
        list.add(30);
//        内部类
       /* Consumer<Integer> consumer = new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        };
        list.forEach(consumer);*/
        /*list.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        });*/

//        list.forEach(t-> System.out.println(t));
//        println(..):有参数没有返回值
       /*Consumer consumer =  System.out::println;
//        方法引用
        list.forEach(consumer);*/

        list.forEach(System.out::println);
    }
}

Stream

 Stream 的操作三个步骤

创建 Stream :一个数据源(如:集合、数组),获取一个流

中间操作 :一个中间操作链,对数据源的数据进行处理

终止操作(终端操作) :一个终止操作,执行中间操作链,并产生结果

 创建 Stream 4 种方法

•通过Collection中的steam()方法创建流
•通过Collection中的parallelSteam()方法创建流
•通过Arrays中的steam()方法创建流
•通过Stream中的of()静态方法创建流
•通过Stream中的iterate()方法创建流
•通过Steam中的generate()方法创建流

 常见Stream接口的继承关系

Stream的中间操作

       多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理而在终止操作时一次性全部处理,称为“惰性求值”。

 上面这个例子主要是对一组String数据进行操作,主要涉及到的中间操作方法有filter(),limit(),skip(),distinct()终止操作方法有forEach(),下面我们对这些常用方法进行简单介绍

 中间操作常用方法

分类

方法

描述

筛选和切片

filter(Predicate p)

接收Lambda,从流中排除某些元素

limit(long maxSize)

截断流,使其元素不超过给定数量

skip(long n)

跳过元素,返回一个跳过前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补

distinct()

筛选,通过流所生成元素的hashCode()equals()去除重复元素

映射

map(Function f)

接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素

mapToDouble(ToDoubleFunction f)

接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的DoubleStream

mapTolnt(ToIntFunction f)

同上

mapToLong(ToLongFunction f)

同上

flatMap(Function f)

接收一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有流连接成一个流

排序

sorted()

产生一个新流,其中按自然顺序排序

sorted(Comparator c)

产生一个新流,其中按比较器顺序排序

 Stream的终止操作

分类

方法

描述

查找与匹配

allMatch(Predicate p)

检查是否匹配所有元素

anyMatch(Predicate p)

检查是否至少匹配一个元素

findFirst()

检查是否没有匹配所有元素返回第一个元素

findAny()

返回当前流中的任意元素

count()

返回流中元素总数

max(Comparator c)

返回流中最大值

min(Comparator c)

返回流中最小值

forEach()

内部迭代

归约

reduce(T iden, BinaryOperator b)

可以将流中元素反复结合起来,得到一个值。返回T

reduce(BinaryOperator b)

可以将流中元素反复结合起来,得到一个值。返回 Optional

收集

collect(Collector c)

将流转换为其他形式。接收一个 Collector 接口的实现,用于给 Stream 中元素做汇总的方法

 演示

 Stream的终止操作-collect()

  Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 ListSet/Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

方法

返回类型

作用

toList

List

把流中元素收集到 List

toSet

Set

把流中元素收集到 Set

toCollection

Collection

把流中元素收集到 Collection

counting

Long

计算流中元素的个数

summingInt

Integer

对流中元素的整数属性求和

averagingInt

Double

计算流中元素Integer属性的平均值

summarizingInt

IntSummaryStatistics

收集流中Integer属性的统计值,如:平均值

joining

String

连接流中每个字符串

maxBy

Optional

根据比较器选择最大值

minBy

Optional

根据比较器选择最小值

reducing

归约产生的类型

收集流中Integer属性的统计值,如:平均值

collectingAndThen

转换函数返回的类型

包裹另一个收集器,对其结果转换函数

groupingBy

Map<K, List>

根据某属性值对流分组,属性为K,结果为V

partitioningBy

Map<Boolean, List>

根据truefalse进行分区

 

 

 

 示例代码演示

package part5;

import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @date : 2022/11/23 14:30
 */
public class JunitStream {


    /**
     * 数据源(集合、数组、变量、字符串。。。)---》Stream流对象
     * 1、创建Stream流对象
     */
    @Test
    public void createStream() {

//        list1数据源
        List<Integer> list1 = new ArrayList<>();
        list1.add(10);
        list1.add(30);
        list1.add(20);

//        1)集合对象中 stream()
        Stream<Integer> stream = list1.stream();
        stream.forEach(t -> System.out.println(t));

//         2)集合中方式2
        Stream<Integer> stream2 = list1.parallelStream();
        stream2.forEach(t -> System.out.println(t));

//        3)数组数据源--》Stream
        Integer[] arr = {1, 3, 5, 7};
        Stream<Integer> stream3 = Arrays.stream(arr);


//        4)Stream中的of方法
        Stream<Integer> stream4 = Stream.of(1, 2, 3, 4, 5);
        stream4.forEach(t-> System.out.println(t));


//        5)Stream中iterate
//        数据进行计算:从0开始 让他每次+2 :0 2 4 6 8 10.....
//         iterate无限流
//        Stream<Integer> stream5 = Stream.iterate(0, t -> t + 2);


        //        limit(3) 获取前3个数据
        Stream<Integer> stream6 = Stream.iterate(0, t -> t + 2).limit(3);
        stream6.forEach(t -> System.out.println(t));

        System.out.println("===================");
//        6)Stream.generate
//        Math.random()--double
//        Stream.generate(()->{return Math.random();});
//        Stream.generate(()-> Math.random());
//        Stream<Double> generate = Stream.generate(Math::random);
        Stream<Double> stream7 = Stream.generate(Math::random).limit(2);
        stream7.forEach(t -> System.out.println(t));
//        stream7.forEach(System.out::println);


    }


    /**
     * 2、流操作:
     * 中间操作
     */
    @Test
    public void operation() {
        Stream<String> stream = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");

//      1)中间操作-->新Stream流
//      filter:过滤流  返回true条件都会添加到这个新流当中
        Stream<String> newStream = stream.filter(str -> {
            if (",".equals(str)) {
                return false;
            } else {
                return true;
            }
        });

        newStream.forEach(t -> System.out.println(t));

        System.out.println("---------------------------");

        Stream<String> stream2 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");

//        中间操作--limit  获取前X个数据
        Stream<String> newStream2 = stream2.limit(2);

        newStream2.forEach(t -> System.out.println(t));


        System.out.println("------1111111111----------------------------");
        Stream<String> stream3 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");

//        中间操作---skip跳过前多少个数据
        Stream<String> streamNew = stream3.skip(2);
        streamNew.forEach(t -> System.out.println(t));

        System.out.println("----distict:-----------------------------");
        Stream<Integer> streamDistinct = Stream.of(10, 20, 30, 10, 5);
//         中间操作去重--distinct
        Stream<Integer> newDistinctStream = streamDistinct.distinct();
        newDistinctStream.forEach(t -> System.out.println(t));


//        数组  1,3,7,8,9,2,4,7,2----去重后求其数据个数
        Integer[] arr2 = {1, 3, 7, 8, 9, 2, 4, 7, 2};
        Stream<Integer> stream1 = Arrays.stream(arr2);
        long count = stream1.distinct().count();
        System.out.println("count:" + count);


        Stream<String> stream4 = Stream.of("Tom", ",", "Hello", " ", "Hello", "World");
//        Stream<String> count1 = stream.filter(str -> !",".equals(str) ? true : false).limit(3).skip(1).distinct();
//        中间流  可以使用连续操作---链式编程
        long count1 = stream4.filter(str -> !",".equals(str) ? true : false).limit(3).skip(1).distinct().count();
        System.out.println("count1:" + count1);

        System.out.println("=========sorted=============");
        Integer[] arr = {1, 3, 7, 8, 9, 2, 4, 7, 2};
//        使用流的操作:数组去重  按照升序进行输出
        Stream<Integer> stream5 = Arrays.stream(arr);
//        按照升序进行输出
//        stream5.distinct().sorted().forEach(t-> System.out.println(t));
//        降序进行输出
        stream5.distinct().sorted((a1, a2) -> a2.compareTo(a1)).forEach(t -> System.out.println(t));


        System.out.println("flatMap:===================");
//        需求:"e", "d", "c", "a", "f", "b"--->"edcafb"
        Stream<String> stream6 = Stream.of("e", "d", "c", "a", "f", "b");
        stream6.flatMap(t -> Stream.of(t)).forEach(t -> System.out.print(t));

        System.out.println("=============================");

        Integer[] arr66 = {1, 3, 7, 8, 9, 2, 4, 7, 2, 60, 70};
//        分类:>=10归为一类数据    ----》999      <10归为两类----》0
        Stream<Integer> stream66 = Arrays.stream(arr66);
        Stream<Integer> stream661 = stream66.map(t -> t >= 10 ? 999 : 0);
        stream661.forEach(t -> System.out.println(t));

    }


    /**
     * 流操作注意事项:
     * Stream 自己不会存储元素----》:数据源--》转换为流
     * Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream
     * Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
     * Stream 只能被"消费"一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。
     */
    @Test
    public void operation2() {
        Integer[] arr = {1, 3, 7, 8, 9, 2, 4, 7, 2};
        Stream<Integer> stream = Arrays.stream(arr);
        /*Stream<Integer> stream = Arrays.stream(arr);

        Stream<Integer> newStream = stream.skip(2).distinct();

        long count = newStream.count();*/
//        Stream 只能被"消费"一次,一旦遍历过就会失效
        stream.forEach(t -> System.out.println(t));


//        java.lang.IllegalStateException: stream has already been operated upon or closed
        long count = stream.distinct().count();


    }


    /**
     * 2、流操作:
     * 终止操作
     */
    @Test
    public void operation3() {

//        Integer[] arr = {11, 3, 17};
//        Stream<Integer> stream = Arrays.stream(arr);

//        判断数组中至少含有一个大于10数据
//        anyMatch:至少含有一个
       /* boolean result1 = stream.anyMatch(t -> t > 10);
        System.out.println("result1:"+result1);*/

//        判断数组中所有的数据都大于5  true
       /* boolean resultALl = stream.allMatch(t -> t >5);
        System.out.println("resultALl:"+resultALl);*/


//   求 数组中所有元素之和
       /* Optional<Integer> reduce = stream.reduce((num1, num2) -> num1 + num2);
        Integer sum = reduce.get();
        System.out.println("sum:"+sum);*/


//        求 数组中所有数据乘积
        /*Optional<Integer> reduce2 = stream.reduce((num1, num2) -> num1 * num2);
        Integer result = reduce2.get();
        System.out.println("result:"+result);

        Stream<String> streamNew = Stream.of("a", "b", "c");

        Optional<String> reduce3 = streamNew.reduce((str1, str2) -> str1 + str2);
        String str = reduce3.get();
        System.out.println(str);*/

     /*   Integer[] arr1 = {1, 2, 3, 4, 5};
        Stream<Integer> stream1 = Arrays.stream(arr1);
//        求 数组中所有奇数和
        Optional<Integer> reduce7 = stream1.filter(t -> t % 2 != 0).reduce((a, b) -> a + b);
        Integer result77 = reduce7.get();
        System.out.println(result77);*/


//        System.out.println("=======collect:=流--》集合对象转换===============");

        /*Stream<String> stream2 = Stream.of("e", "d", "c", "a", "f", "b");    //把流中元素收集到


        List<String> list = stream2.collect(Collectors.toList());   // 调用终止操作的方法后需要重新定义


        Stream stream = Stream.of("e", "d", "c", "a", "f", "b");   // 把流中元素收集到

        Set<String> set = stream2.collect(Collectors.toSet());

        stream = Stream.of("e", "d", "c", "a", "f", "b");
//         把流中元素收集到 Collection(ArrayList)
//         ArrayList::new 等同于()->new ArrayList()
//         ArrayList::new 可以是list,set接口下的任意实现类
        ArrayList<String> alist = stream2.collect(Collectors.toCollection(ArrayList::new));
        System.out.println(list); // [e, d, c, a, f, b]
        System.out.println(set); // [a, b, c, d, e, f]
        System.out.println(alist); // [e, d, c, a, f, b]
*/

        System.out.println("====collect===Collectors:功能===============");


        Integer[] arr2 = {1, 2, 3, 4, 5};
        Stream<Integer> stream1 = Arrays.stream(arr2);
//        计数
        /*Long count = stream1.collect(Collectors.counting());
        System.out.println("count:"+count);*/

//   求和
        Integer sum = stream1.collect(Collectors.summingInt(t -> t));
        System.out.println("sum:"+sum);


        System.out.println("========================");

//        groupingBy:   分班 java314 精英班  成绩要求都是80分(含)以上     80分以下分数---java00
        Integer[] scores = {85, 90, 100, 70, 80,75};
//        java314---》 85 90 100 80
//        java00--->70 75

        Stream<Integer> stream = Arrays.stream(scores);
        Map<String, List<Integer>> map = stream.collect(Collectors.groupingBy(t -> t >= 80 ? "java314" : "java00"));
        map.forEach((k,v)-> System.out.println(k+"----"+v));


    }


}

 作业

package part5;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author : cqq
 * @date : 2022/11/23 13:13
 */
public class Task {

    public static void main(String[] args) {

//        1.	给一个整数集合,分别求集合中偶数和与奇数和

        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);
        list1.add(5);
        list1.add(6);
        list1.add(7);
        list1.add(8);
        list1.add(9);
        list1.add(10);

//        list1.stream().filter(t->t%2==0).forEach(a-> System.out.println(a));
        Optional<Integer> reduce = list1.stream().filter(t -> t % 2 == 0).reduce((x, y) -> x + y);
        Integer ou = reduce.get();
        System.out.println("ou和:"+ou);
//        list1.stream().filter(t->t%2!=0).forEach(a-> System.out.println(a));
        Optional<Integer> ji = list1.stream().filter(t -> t % 2 != 0).reduce((x, y) -> x + y);
        System.out.println("ji和:"+ji.get());
//
//
//
//
//
       System.out.println("---------------------");
//        2. 给一个整数集合,将集合分成偶数集合和奇数集合
        ArrayList<Integer> li = new ArrayList<>();
        li.add(1);
        li.add(2);
        li.add(3);
        li.add(4);
        li.add(5);
        li.add(6);
        List<Integer> ou1 = li.stream().filter(t->t%2==0).collect(Collectors.toList());
        System.out.println("ou:"+ou1);
        List<Integer> ji1 = li.stream().filter(t->t%2!=0).collect(Collectors.toList());
        System.out.println("ji:"+ji1);



/*//        List<Integer> list22 = list1.stream().filter(t -> t % 2 == 0).collect(Collectors.toList());
        List<String> list66 = list1.stream().map(t -> t + "").collect(Collectors.toList());
        System.out.println(list66);


        System.out.println("---------888888888888------------");
        List list7 = new ArrayList<>();
        list7.add("hello");
        list7.add(2);
        System.out.println(list7);

        System.out.println("===========999999999:=============");
//
//*/
//
//        3. 集合转换:[[1, 2, 3, 4, 5], [2, 1, 9, 3, 6, 7], [3, 1, 6]] -> ["1", "2", "4", "5", "2", …… "3", "1","6"]
        List<Integer> list4 = new ArrayList<>();
        List<Integer> list2 = new ArrayList<>();
        List<Integer> list3 = new ArrayList<>();

        Collections.addAll(list4,1,2,3,4,5);
        Collections.addAll(list2,3,1,6);
        Collections.addAll(list3,2,1,9,3,6,7);
        List<String> list = new ArrayList<>();
        list1.stream().map(t -> list.add("“"+t+"”")).collect(Collectors.toList());
        list2.stream().map(t -> list.add("“"+t+"”")).collect(Collectors.toList());
        list3.stream().map(t -> list.add("“"+t+"”")).collect(Collectors.toList());
        System.out.println(list);


/*        List<Integer> list99 = new ArrayList<>();
        list99.add(1);
        list99.add(2);
        list99.add(3);

        List<Integer> list5 = new ArrayList<>();
        list5.add(11);
        list5.add(21);
        list5.add(31);

        List<Integer> list88 = new ArrayList<>();
        list88.add(88);
        list88.add(99);

        list5.stream().map(t -> list99.add(t)).collect(Collectors.toList());
        System.out.println(list99);
        System.out.println("list................");

        list88.stream().map(t -> list99.add(t)).collect(Collectors.toList());
        System.out.println(list99);


//        Stream<String> stringStream = Stream.of("e", "d", "c", "a", "f", "b");
//        String st = stringStream.reduce("", (str1, str2) -> str1 = str1 + str2);
//        System.out.println(st);*/


    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值