javase-day08

aLambda_01InnerClassDemo

package com.se.aLambda;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class _01InnerClassDemo {
    public static void main(String[] args) {
        List<Person> ps = new ArrayList<>();
        ps.add(new Person("张三", 19));
        ps.add(new Person("李四", 20));
        ps.add(new Person("micheal", 18));
        ps.add(new Person("tom", 19));
//        Collections.sort(ps);
//        System.out.println(ps);

        //按照年龄降序排序
//        Comparator c = new Comparator<Person>() {
//            @Override
//            public int compare(Person o1, Person o2) {
//                return o2.getAge() - o1.getAge();
//            }
//        };
        Collections.sort(ps, (o1, o2) -> o2.getAge() - o1.getAge());
        System.out.println(ps);
    }
}

//类一旦定义完,不要轻易修改源代码
class Person implements Comparable<Person> {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

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

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

    @Override
    public int compareTo(Person o) {
        return age - o.age;

    }
}

aLambda_02LambdaDemo

package com.se.aLambda;

/**
 * Lambda 表达式的应用:
 * 1. Lambda表达式实际上就是匿名内部类的简化版本
 * 2. Lambda表达式是jdk1.8引入的一个重要的特性,另一个是集合的流式编程
 * 3. Lambda表达式是java为了扩展函数式编程引用的
 * 4. Lambda表达式可以理解为是一个匿名函数(匿名方法:方法名没名字)
 * 5. Lambda表达式只能作用于函数式接口(有且只有一个抽象方法的接口)
 */

public class _02LambdaDemo {
    public static void main(String[] args) {
        //2. 测试实现类
        NoParameterNoReturn class1 = new class1();
        class1.print();


        //3. 使用匿名内部类的方式,实现NoParameterNoReturn接口打印“java.ez”
        NoParameterNoReturn nono = new NoParameterNoReturn() {
            @Override
            public void print() {
                System.out.println("哈哈哈,我哭了");
            }
        };
        nono.print();

        //4. 使用Lambda表达式,实现NoParameterNoReturn接口打印“java.ez”
        NoParameterNoReturn n1 = () -> System.out.println("java.ez");
        n1.print();

        //5. 使用Lambda表达式,实现OneParameterNoReturn接口打印“我喜欢”+参数,传入苹果
        OneParameterNoReturn oneNoReturn = info -> System.out.println("我喜欢" + info);
        oneNoReturn.print("苹果");

        //6. 使用lambda表达式,实现MuilParameterNoReturn接口,打印两个参数拼接的效果,测试传入"我今年""18"
        MuilParameterNoReturn muilNoReturn = (info, age) -> System.out.println(info + age);
        muilNoReturn.print("我今年", 18);

        //7. 使用lambda表达式,实现NoParameterReturn接口,计算两个随机数,区间[25,40]的和","
        NoParameterReturn noParameterReturn1 = () ->
                (int) (Math.random() * 16 + 25)
                        + ((int) (Math.random() * 16 + 25));
        System.out.println(noParameterReturn1.calculate());

        //8. 使用lambda表达式,实现0neParameterReturn接口,计算形参的立方,测试传入3
        OneParameterReturn oneR2 = a -> a * a * a;
        System.out.println(oneR2.calculate(3));


        //9. 使用lambda表达式,实现MuilParameterReturn接口,计算两个形参的立方和,测试传入3和4
        MuilParameterReturn mR1 = (int a, int b) -> a * a * a + b * b * b;
        System.out.println(mR1.calculate(3, 4));


    }
}

//1. 使用实现类的方法,实现NoParameterNoReturn接口
class class1 implements NoParameterNoReturn {
    @Override
    public void print() {
        System.out.println("java.ez");
    }
}

//里面的抽象方法,没有形参,也没用返回值
interface NoParameterNoReturn {
    void print();
}

//一个形参,没有返回值
interface OneParameterNoReturn {
    void print(String info);
}

//多个形参,无返回值
interface MuilParameterNoReturn {
    void print(String info, int age);
}

//没有形参,有返回值
@FunctionalInterface //注解是用来校验是否是函数式接口
interface NoParameterReturn {
    int calculate();
}

//一个形参,有返回值
interface OneParameterReturn {
    int calculate(int a);
}

//多个形参,有返回值
interface MuilParameterReturn {
    int calculate(int a, int b);
}

aLambda_03LambdaDemo02

package com.se.aLambda;

import java.util.*;

/**
 * 第一个:排序时,使用比较器的时候
 * 第二个:迭代时
 * 第三个:根据条件删除元素
 */

public class _03LambdaDemo02_InList {
    public static void main(String[] args) {
        //测试第一种
        List<String> list = new ArrayList<>();
        list.add("michael");
        list.add("david");
        list.add("bob");
        list.add("lucy");
        //按照字符串的长度降序: 比较器使用lambda表达的方法
        Collections.sort(list, (a,b)->b.length()-a.length());
        System.out.println(list);


        //测试第二种: 集合的迭代
        Integer[] arr = new Integer[]{4,5,10,7,2};
        List<Integer> nums = Arrays.asList(arr);
        /*
          forEach(Consumer c)的源码:
           for(T t : this){
               c.accept(t);
               }

               Consumer是一个函数式接口:里面的抽象方法
               void accept(T t);

               因此只需要向forEach()方法中传入 accept的匿名函数,也就是lambda表达式即可
        */
        nums.forEach((num-> System.out.println(num)));
        //继续简化
        nums.forEach(System.out::println);

        //Set类型的迭代
        Set<Integer> set = new HashSet<>(nums);
        System.out.println(set);
        set.forEach(System.out::println);

        //Map的迭代
        Map<String,Integer> map = new HashMap<>();
        map.put("张三", 18);
        map.put("李四", 19);
        map.put("王五", 17);
        map.put("赵六", 28);
        //Key的迭代
        map.keySet().forEach(key-> System.out.println(key));
        //entrySet的迭代
        map.entrySet().forEach(entry-> System.out.println(entry.getKey()+" "+entry.getValue()));
        //value的迭代
        map.values().forEach(value-> System.out.println(value));


        //测试第三种:根据条件删除元素
        List<Integer> ages = Arrays.asList(18,19,17,20,17);
        List<Integer> ages2 = new ArrayList<>(ages);
        /*
          removeIf(Predicate filter(过滤器)):  满足条件就会删除
           源码解析:
             内部逻辑就是一个迭代器遍历集合,根据条件做删除操作
             条件就是filter的test方法
           Predicate是一个函数式接口,里面有boolean test(T t)方法
           因此我们在使用时就是写一个lambda表达式来实现test方法即可
        */
        ages2.removeIf(age->age.equals(17));
        System.out.println(ages2);
    }
}

bVariableCatch_01InnerClassDemo

package com.se.bVariableCatch;

/**
 * 变量的捕获: 在内部对外部的变量的引用和访问
 *  1. 实例变量(成员变量,属性,全局变量)
 *  2. 静态变量
 *  3. 本地形参
 *  4. 本地变量(局部变量)
 *
 *  总结:
 *  1. 匿名内部类访问的变量,只能访问不能覆盖
 *  2. Lambda表达式,也可以访问上述四种变量,依然是对局部变量只能访问,不能覆盖。
 */

public class _01InnerClassDemo {
    private int a;  //实例变量
    private static int b; //静态变量

    static {
        b = 2;
    }

    public _01InnerClassDemo(){
        a = 1;
    }
    public void m1(int c){
        int d = 4;
        MyTest mt = new MyTest() {
            @Override
            public void test1() {
                //访问外部类的成员变量:外部类名.this.成员变量  或者直接写
                System.out.println("instance variable:"+ a);
                //访问外部类的静态变量:外部类名.静态变量  或者直接写
                System.out.println("static variable:"+ b);
                //匿名内部类访问的方法形参,也只能访问,不能覆盖。
                System.out.println("method parameter:"+ c);
                //匿名内部类访问的局部变量是默认被final修饰的,final修饰的变量只能初始化一次,不能被第二次赋值
                System.out.println("local variable:"+ d);
                //  c = 10;  d = 5;
            }

        };
        //调用test1方法
        mt.test1();

    }

    public void m2(int c){
        int d = 4;
        MyTest mt = () -> {
            //访问外部类的成员变量:外部类名.this.成员变量  或者直接写
            System.out.println("instance variable:"+ a);
            //访问外部类的静态变量:外部类名.静态变量  或者直接写
            System.out.println("static variable:"+ b);
            //访问的方法形参,也只能访问,不能覆盖。
            System.out.println("method parameter:"+ c);
            //访问的局部变量是默认被final修饰的,final修饰的变量只能初始化一次,不能被第二次赋值
            System.out.println("local variable:"+ d);
        };
        mt.test1();
    }


    public static void main(String[] args){
        //测试:创建外部类对象,调用m1方法
        _01InnerClassDemo c1 = new _01InnerClassDemo();
//        c1.m1(3);
        c1.m2(3);
    }
}
interface MyTest{
    void test1();

}

cStream_01DataSourceGet

package com.se.cStream;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * 集合的流式编程:
 *   1. 传统方式,如果对集合中的元素做处理时,可能要书写大量代码,比如增删过滤等
 *   2. 集合的流式编程,是JDK1.8引入的两个重要特征之一
 *   3. 集合的流式编程是对传统方式的一种简化操作
 *   4. 集合的流式编程分三步:
 *         -第一步:获取数据源(关联数据源),返回Stream对象
 *         -第二步:对Stream对象进行各种处理,处理后结果依旧是Stream对象
 *         -第三步:对Stream对象的最后整合处理,处理后的结果,一般情况下不再是Stream对象
 *                   可能是一个具体的数字,字符串或者一个新的集合。
 *
 *     tips:整个过程中,数据源本身不会发生变化
 */

public class _01DataSourceGet {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);

        /*
          如果想要对这个集合进行流式处理,必须先获得数据源
         */
        //  1. 获取的流对象,是串行的,不是并行的
        Stream<Integer> stream = nums.stream();
        //  2. 对流对象进行各种处理,返回新的流对象
        Stream<Integer> stream1 = nums.parallelStream();

    }
}

cStream_02Final_collect

package com.se.cStream;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 集合流式编程的最终操作:
 *   1. 将流中的的数据整合到一起,可以存入一个新的集合,也可以遍历或者统计
 *   2. 最终操作,会关闭这个流。流中的数据都会被销毁。  关闭流之后继续操作流会报错
 *
 *    最终操作常用方法如下:
 *      1. collect: 搜集方法可以将流的数据搜集成一个新的集合
 *                    该方法的形参是Collector接口(非函数式接口),可以用了知制定搜索规则
 *                    通常情况下,不需要程序员自己实现,Collectors工具类里提供的方法够用
 */

public class _02Final_collect {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);

        //获取数据源
        Stream<Integer> Stream = nums.stream();
        //搜集1  凑集为List集合
        List<Integer> c1 = Stream.collect(Collectors.toList());
        System.out.println(c1 == nums);

        //搜集2  凑集为Set集合
        Set<Integer> c2 = Stream.collect(Collectors.toSet());
        System.out.println(c2 == nums);

        /*
          搜集3  搜集成Map集合
           Collectors.toMap(keyMapper, valueMapper)
           KeyMapper是函数式接口,里面只有一个R apply(T t) 抽象方法,我们就是通过lambda表达式来重写apply方法
           valueMapper亦如此
         */
        Map<String, Integer> c3 = Stream.collect(Collectors.toMap((e) -> "key" + e, e -> e));
        System.out.println(c3);

    }
}

cStream_03Final_reduce

package com.se.cStream;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public class _03Final_reduce {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);
        Stream<Integer> stream = nums.stream();
        /*
          计算数据源的元素之核 方法参数也是lambda表达式  对应的抽象方法 R apply(T t ,U u);
          返回的类型:Optional,需要调用官的get方法,获取里面的数据
          Optional<Integer> reduce = stream.reduce((a, b) -> (a + b)); //15
         */

        //a变量接受的是数据源中的第一个元素,然后b变量接受的是剩下的元素  a与b的关系是:a -= b
        Optional<Integer> reduce = stream.reduce((a, b) -> (a - b)); //-13
        int result = reduce.get();
        System.out.println("计算结果:" + result);
    }
}

cStream_04Final_count

package com.se.cStream;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class _04Final_count {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);
        Stream<Integer> stream = nums.stream();

        /*
          count是用于统计数据源的元素个数
          底层源码: return mapToLong(e -> 1L).sum();
                即将元素映射成1,然后求和。
         */
        long count = stream.count();
        System.out.println(count);
    }
}

cStream_05Final_forEach_max_min

package com.se.cStream;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class _05Final_forEach_max_min {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);
        Stream<Integer> stream = nums.stream();


        //forEach方法,对流中的数据进行遍历,遍历完毕,流就关闭了
        stream.forEach(num -> System.out.println(num));
        stream.forEach(System.out::println);

        // max方法,返回流中最后的元素
        int max = stream.max((a, b) -> a - b).get();
        System.out.println(max);

        // min方法,返回流中最前的元素
        int min = stream.min((a, b) -> a - b).get();
        System.out.println(min);

    }
}

cStream_06Final_Matching

package com.se.cStream;

import java.util.ArrayList;
import java.util.List;

/**
 * AllMatch: 当数据源中的所有元素都满足匹配条件,才返回true
 * AnyMatch: 当数据源中的任意一个元素满足匹配条件,则返回true
 * NoneMatch: 当数据源中的所有元素都不满足匹配条件,才返回true
 */

public class _06Final_Matching {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);
        boolean b = nums.stream().allMatch(e -> e < 10);
        System.out.println(b);
        boolean b1 = nums.stream().anyMatch(e -> e > 2);
        System.out.println(b1);
        boolean b2 = nums.stream().noneMatch(e -> e > 10);
        System.out.println(b2);

    }

}

cStream_07Final_find

package com.se.cStream;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * FindFirst:
 * FindAny:
 *
 * 上述两个方法,针对于串行的流,获取的都是第一个元素
 *              针对于并行的流,获取的元素应该不同
 */

public class _07Final_find {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);
        Stream<Integer> stream = nums.stream();

        //串行的流演示
        int e1 = nums.stream().findFirst().get();
        System.out.println(e1);
        int e2 = nums.stream().findAny().get();
        System.out.println(e2);

        //并行的流演示
        Integer e3 = nums.parallelStream().findFirst().get();
        System.out.println(e3);
        Integer e4 = nums.parallelStream().findAny().get();
        System.out.println(e4);

    }
}

dStreamMiddel_01Filter_Distinct

package com.se.dStreamMiddel;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class _01Filter_distinct {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);
        nums.add(2);
        nums.add(4);


        /**
         *  filter(...) 过滤出来满足条件的数据,
         *  比如,想要所有的奇数
         */
        List<Integer> c1 = nums.stream().filter(x -> x%2!=0).collect(Collectors.toList());
        System.out.println(c1);

        /**
         *  distinct() 去重   Lambda表达式 可以理解为一个没有名字的方法
         *
         *  int a  给a赋值, 传递的是具体数据 或者变量
         *  forEach(....表达式..)
         */
        nums.stream().distinct().forEach(Class1::m1);


    }
}

class Class1{
    public static<T> void m1(T t){
        System.out.println(t);
    }
}

dStreamMiddel_02Sorted_limit_skip

package com.se.dStreamMiddel;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class _02Sorted_limit_skip {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(3);
        nums.add(2);
        nums.add(5);
        nums.add(4);
        nums.add(1);
        Stream<Integer> stream = nums.stream();

        //sorted() 升序排序  sorted(Comparator c) 自定义比较规则
        nums.stream().sorted((a, b) -> b - a).forEach(System.out::println);

        //limit(long size) 截取  :表示截取流中的前size个元素
        nums.stream().limit(2).sorted((a, b) -> a - b).forEach(System.out::println);

        //skip(long size) 跳过  :表示跳过流中的前size个元素
        nums.stream().filter(e -> e != 2).sorted().skip(2).forEach(System.out::println);
    }
}

dStreamMiddel_03Map_mapToInt

package com.se.dStreamMiddel;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class _03Map_mapToInt {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.add(5);
        Stream<Integer> stream = nums.stream();

        //map(...): 将元素映射成另外一种类型  例如将上述的元素映射成字符串类型
        List<String> c1 = nums.stream().map(e -> "" + e).collect(Collectors.toList());
        System.out.println(c1);

        /*
          mapToInt(...): 将元素映射成int类型
          mapToLong(...): 将元素映射成long类型
          mapToDouble(...): 将元素映射成double类型
         */

        int sum = nums.stream().mapToInt(e -> 1).sum();
        System.out.println(sum);

    }
}

dStreamMiddel_04FlatMap

package com.se.dStreamMiddel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * flatMap: 扁平式映射。
 *    一般针对的都是集合元素仍然是一个集合。
 *    普通的集合[1,2,3,4,5]
 *    集合元素是几个的: [[1,2,10],[1,3,4],[2,4,5]]
 *
 *    扁平式映射: 就是将元素是集合的这种特殊集合,转成普通的集合
 *      如 [[1,2],[1,3,4],[2,4,5]]  =>  [1,2,10,1,3,4,2,4,5]
 */

public class _04FlatMap {
    public static void main(String[] args) {
        //集合out的元素仍然是集合
        List<List<Integer>> out = new ArrayList<>();
        out.add(Arrays.asList(1,2,10));
        out.add(Arrays.asList(1,3,4));
        out.add(Arrays.asList(2,4,5));

        //flatMap(.....) 传入一个lambda表达式 : e->e.stream()  压平了。
        long count = out.stream().flatMap(e -> e.stream()).count();
        System.out.println("集合元素是几个的: " + count);

        double asDouble = out.stream().flatMap(e -> e.stream()).mapToInt(e -> e).average().getAsDouble();
        System.out.println(asDouble);

    }
}

exercise_Program

package com.se.exercise;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 需求 : 一个集合中存储了了若干个Student对象 , 要求查询出以下结果 :
 * 1. 所有及格的学生信息
 * 2. 所有及格的学生姓名
 * 3. 所有学生的平均成绩
 * 4. 班级的前3名(按照成绩)
 * 5. 班级的3-10名(按照成绩)
 * 6. 所有不及格的学生平均成绩
 * 7. 将及格的学生 , 按照成绩降序输出所有信息
 * 8. 班级学生的总分
 */
public class Program {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student("A", 90));
        list.add(new Student("B", 80));
        list.add(new Student("C", 70));
        list.add(new Student("D", 60));
        list.add(new Student("E", 50));
        list.add(new Student("F", 40));
        list.add(new Student("G", 30));
        list.add(new Student("H", 20));
        list.add(new Student("I", 10));
        list.add(new Student("J", 0));


        System.out.println("1. 所有及格的学生信息:");
        list.stream().filter(x -> x.getScore()>=60).forEach(System.out::println);

        System.out.println("2. 所有及格的学生姓名:");
        list.stream().filter(x->x.getScore()>=60).map(x->x.getName()).forEach(System.out::println);

        System.out.println("3. 所有学生的平均成绩:");
        System.out.println(list.stream().collect(Collectors.averagingInt(Student::getScore)));

        System.out.println("4. 班级的前3名(按照成绩):");
        list.stream().sorted((a,b)->b.getScore()-a.getScore()).limit(3).forEach(System.out::println);

        System.out.println("5. 班级的3-10名(按照成绩):");
        list.stream().sorted((a,b)->b.getScore()-a.getScore()).skip(2).forEach(System.out::println);

        System.out.println("6. 所有不及格的学生平均成绩:");
        System.out.println(list.stream().filter(x->x.getScore()<=60).collect(Collectors.averagingInt(Student::getScore)));

        System.out.println("7. 将及格的学生 , 按照成绩降序输出所有信息:");
        list.stream().filter(x->x.getScore()>=60).sorted((a,b)->b.getScore()-a.getScore()).forEach(System.out::println);

        System.out.println("8. 班级学生的总分:");
        System.out.println(list.stream().collect(Collectors.summingInt(Student::getScore)));


    }


}


exercise_Student

package com.se.exercise;

public class Student {
    private String name;
    private int score;

    public String getName() {
        return name;
    }

    public int getScore() {
        return score;
    }

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return String.format("姓名 : %s, 成绩 : %d", name, score);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值