Java 函数式编程(1 万字)

news2024/11/24 6:26:47

此笔记来自于B站黑马程序员 good
Java 历史版本及其优势

在这里插入图片描述

函数式编程, Stream API

一.函数伊始函数、函数对象

函数对象

行为参数法

image-20241007123851139

image-20241007124037094

image-20241007124243417

延迟执行

image-20241007124718046

image-20241007124849860

a-lambda

image-20241007135452414

b-方法引用

image-20241007140002122

复习小测

image-20241007140721800

  1. Math::random
    () -> Math.random()
  2. Math::sqrt
    (double number) -> Math.sqrt(number)
  3. Student::getName
    (student stu) -> stu.getName()
  4. Student::setName
    (Student stu,String newName) -> stu.setName(newName)
  5. Student::hashcode
    (student stu) -> stu.hashcode()
  6. Student::equals

​ (Student stu, object o) -> stu.equals(o)

假设已有对象 Student stu = new Student(“张三”);
  1. stu::getName

​ () -> stu.getName()

  1. stu::setName

​ (String newName) -> stu.setName(newName)

  1. Student::new

​ (String name) -> new Student(name)

二.函数编程语法 Lambda、方法引用、闭包、柯里化、高阶函数

函数对象类型

image-20241007141519019

import java.util.List;
import java.util.function.Function;
import java.math.BigInteger;
import java.util.ArrayList;

public class CategoryTest {
    static class Student{
        private String name;
        public Student(String name) {
        	this.name = name;
        }
        public String getName() { return name; }
        public void setName(String name) {this.name=name;}
        @Override
        public boolean equals(object o){...}
        @0verride
        public int hashCode() { return Objects.hash(name);}
    }
   
   public static void main(String[] args) {
       IntPredicate(int a) -> (a & 1) == 0;
       IntPredicate(int a) -> BigInteger.valueOf(a).isProbablePrime(100);
       (int a, int b, int c) -> a + b + c;
       IntBinaryOperator(int a, int b) -> a - b;
       IntBinaryOperator(int a, int b) -> a * b;
       Supplier<Student>() -> new Student();
       Supplier<List<Student>>() -> new ArrayList<Student>();
       Function<Studetn, String> obj8 <String, Student> obj8 = (Student s) -> s.getName();
       Function<Student, Integer> obj9 (Type7)<Integer, Student> obj9 = (Student s) -> s.getAge();
   }
    
    @FunctionalInterface
    interface Type1 {
        boolean op(int a); // 只能有一个抽象方法
    }
    
    @FunctionalInterface
    interface Type7<O, I> {
        O op(I input);
    }
}

常见的函数接口

image-20241007152935426

image-20241007153356440

使用函数接口来解决问题

public class test04 {
    public static void main(String[] args) {
        
        List<Integer> result = supply(5, () -> ThreadLocalRandom.current().nextInt());
        System.out.println(result);
    }
    
    static List<Integer> filter(List<Integer> list, Predicate<Integer> predicate) { ... };
    static List<String> map(List<Integer> list, Function<Integer, String> func) { ... };
    static void consume(List<Integer> list, Consumer<Integer> consumer) { ... }
    
    static List<Integer> supply(int count, Supplier<Integer> supplier) {
        List<Integer> result = new ArrayList<>();
        
        for (int i = 0; i < count; i++) {
            // 生成:随机数,但以后可能改变生成规则
            result.add(supplier.get());
        }
        
        return result;
        /**
        	() -> ThreadLocalRandom.current().nextInt();
        */
    }
}

方法引用

在这里插入图片描述

类名:静态方法

image-20241007160202182

public class MethodRef1 {
    public static void main(String[] args) {
        /*
        	需求:挑选出所有男性学生
        */
        Stream.of (
        		new Student("张无忌", "男"),
            	new Student("周芷若", "女"),
            	new Student("宋青书""男")
        )
            // .filter(stu -> stu.sex().equals("男")); lambda 表达式方式
            .filter(MethodRef1::isMale);
        	// .forEach(sut -> System.out.println(sut)) lambda 表达式方式
        	.forEach(MethodRef1::abc); // 静态方法引用方式
        /*
        	(Student stu) -> stu.sex().equals("男")
        	(Student stu) -> MethodRef1.isMale(stu)
        */
        
        public static boolean isMale(Student stu) {
        	return stu.sex().equals("男");    
        }
        
        public static void abc(Student stu) {
            System.out.println(stu);
        }
        
    }
}
类名:非静态方法

image-20241007162258177

public class MethodRef1 {
    public static void main(String[] args) {
        /*
        	需求:挑选出所有男性学生
        */
        Stream.of (
        		new Student("张无忌", "男"),
            	new Student("周芷若", "女"),
            	new Student("宋青书""男")
        )
            // .filter(stu -> stu.sex().equals("男")); lambda 表达式方式
            .filter(MethodRef1::isMale);
        	// .forEach(sut -> System.out.println(sut)) lambda 表达式方式
        //	.forEach(MethodRef1::abc); // 静态方法引用方式
        	.forEach(Student::print);
        /*
        	(Student stu) -> stu.sex().equals("男")
        	(Student stu) -> MethodRef1.isMale(stu)
        */
        
        public static boolean isMale(Student stu) {
        	return stu.sex().equals("男");    
        }
        
        public static void abc(Student stu) {
            System.out.println(stu);
        }
        
        record Student(String name, String sex) {
            public void print() {
                System.out.println(this);
            }
            /**
            * Student::print
            * (stu) -> stu.print()
            */
        }
    }
}

在这里插入图片描述

public class MethodRef3 {
    static class Util {
        public boolean isMale(Student stu) {
            return stu.sex().equals("男");
        }
    }
    
    public static void main(String[] args) {
        Util uitl = new Util();
        Stream.of (
        	new Student("张无忌", "男"),
            new Student("周芷若", "女"),
            new Student("宋青书""男")
        )
         .filter(util::isMale)
         .map(Student::getName)
         .forEach(System.out::println);
    }
    
    /**
    * (stu) -> util.isMale(stu)
    */
    record Student(String name, String sex) {
        public String getName() {
            return this.name;
        }
        
        /**
        * Student::name
        * stu -> stu.name()
        */
    }
}
构造方法

image-20241007174908470

import java.util.function.Supplier;

@toString
public class MethodRef4 {
    static class Student {
		private final String name;
        private final Integer age;
        
        public Student() { ... }
        
        public Student(String name) { this.name = name }
        
        public Student(String name, Integer age) {this.name = name; this.age = age}
        
        @Override
        public String toString() {
            
        }
    }
    
    public static void main(String[] args) {
        Supplier<Student> s1 = Student::new;
        Function<String, Student> s2 = Student::new;
        BiFunction<String, Integer, Student> s3 = Student::new;
        
        System.out.println(s1.get());
        System.out.println(s2.apply("张三"));
        System.out.println(s3.apply("李四", 25));
    }
}

image-20241007175645967

public class MethodRef5 {
    public static void main(String[] args) {
        Util util = new UtilExt();
        util.hiOrder(Stream.of (
        	new Student("张无忌", "男"),
            new Student("周芷若", "女"),
            new Student("宋青书""男")
        ));
    }
    
    record Student(String name, String sex) { }
    
    static class Util {
        // 过滤男性学生并打印
        private bollean isMale(Student stu) {
            return stu.sex().equals("男");
        }
        
         private boolean isFemale(Student stu) {
            return stu.sex().equals("女");
        }
        
        void hiOrder(Stream<Student> stream) {
            stream
         //       .filter(stu->this.isMale(stu))
                .filter(this.isMale)
                .forEach(System.out::println);
        }
    }
    
    static class UtilExt extends Util {
        // 过滤女性学生并打印
       
        void hiOrder(Stream<Student> stream) {
            stream
                .filter(super::isFemale)
                .forEach(System.out::println);
        }
        
    }
}

在这里插入图片描述

对于无需返回值的函数接口,例如 Consumer 和 Runnable 它们可以配合有返回值的函数对象使用

import java.util.function.Consumer;

public class MethodRef7 {
    public static void main(String[] args) {
        Consumer<Object> x = MethodRef7::print1;
        Function<Object, Integer> y = MethodRef7::print2;
        Consumer<Object> z = MethodRef7::print2;
        
        static void print1(Object obj) {
            System.out.println(obj);
        }
        
        static int print2(Object obj) {
            System.out.println(obj);
            
            return 1;
        }
    }
}
public class Exercise4 {
    record Student(String name) { }
    
    // 写出与下列 lamdba表达式 等价的方法引用
    public static void main(String[] args) {
        Function<String, Integer> lambda1 = Integer::parseInt;
        // Function<String, Integer> lambda = (String s) -> Integer.parseInt(S);
        
        // BiPredicate<List<String>, String> lambda2 = (list, element) -> list.contains(element);
        BiPredicate<List<String>, String> lambda2 = List::contains;
        
        // BiPredicate<Student, Object> lambda3 =  (stu, obj) -> stu.equals(obj);
        BiPredicate<Student, Object> lambda3 = Student::equals;
        
        // Predicate<File> lambda4 = (file) -> file.exists();
        Predicate<File> lambda4 = File::exists;
        
        // Runtime runtime = Runtime.getRuntime();
        
        // Supplier<Long> lambda5 = () -> runtime.freeMemory();
        Supplier<Long> lambda5 = Runtime.getRuntime()::freeMemory;
    }
}
例二
public class Exercise5 {
	record Color(Integer red, Integer green, Integer blue) { }
    
    // 如果想用 'Color::new' 来构造 Color 对象,还应当补充哪些代码
    
    public static void main(Stirng[] args) {
        TrenaryFunction lambda = Color::new; // (Integer, Integer, Integer) -> Color
        
        Color white = lambda.create(255, 255, 255);
        System.out.println(white);
        
    }
    
    @FunctionalInterface
    interface TernaryFunction {
        Color create(Integer red, Integer green, Integer blue);
    }
}
public class Exercise6 {
    /**
    * 传入参数时,分别用
    * 类名::静态方法
    * 类名::非静态方法
    * 来表示 [学生年龄大于等于18] 的条件
    */
    static void highOrder(Predicate<Student> predicate) {
        List<Student> list = List.of(
        	new Student("张三", 18),
            new Student("张三", 17),
            new Student("张三", 20)
        );
        
        for (Student stu : list) {
            if (predicate.test(stu)) {
                System.out.println(stu + "通过测试");
            }
        }
        record Student(String name, int age) {
            boolean abc() {
            	return this.age() >= 18;
        	}
        }
       
        static boolean ageGreaterOrEquals18(Student student) {
            return studetn.age() >= 18;
        }
        
        public static void main(String[] args) {
            highOrder(Exercise6::abc);
            
            /**
            * (Exercise6 obj, Student student) -> obj.abc(student)
            */
        }
    }
    
}

闭包

image-20241007191118724

public class ClosureTest1 {
    
    @FunctionalInterface
    interface Lambda {
        int op(int y);
    }
    
    static void highOrder(Lambda lambda) { System.out.println(lambda.op(1)); }
    
    public static void main(String[] args) {
        /**
        *
        * 函数对象 (int y) -> x + y 与它外部的变量 x 形成闭包
        * effective final <===> final
        */
        final int x = 10;
        highOrder((int y) -> x + y);
        
        stu.d = 40;
        highOrder(lambda);
    }
    
    static int a = 1;
    int b = 2;
    
    static class Student {
        int d;
        public Student(int d) {
            this.d = d;
        }
    }
    
    public static void test(int c) {
        highOrder(y -> a + y);
        highOrder(y -> b + y);
        highOrder(y -> c + y);
    }
}
public class ClosureTest2 {
    
    public static void main(String[] args) throws IOException {
        // 闭包作用:给函数对象提供参数以外的数据
        List<Runnable> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            int k = i + 1;
            Runnable task = () -> System.out.println(Thread.currentThread() + "执行任务" + k);
            list.add(task);
        }
        
        ExecutorService service = Executors.newVirtualThreadPerTaskExcutor();
        for (Runnable task : list) {
            service.submit(task);
        }
        
        System.in.read();
    } 
    
}
public class CarryingOTest {
    @FunctionalInterface
    interface F2 {
        int op(int a, int b);
    }
    
    @FunctionalInterface
    interface Fa {
        Fb op(int a);
    }
    
    @FunctionalInterface
    interface Fb {
        int op(int b);
    }
    
    public static void main(String[] args) {
        // 两个参数的函数对象
        F2 f2 = (a, b) -> a + b;
        System.out.println(f2.op(10, 20));
        
        /**
        * 改造
        * (a) -> 返回另一个参数
        * (b) -> a + b
        */ 
        
        Fa fa = (a) -> (b) -> a + b;
        Fb fb = fa.op(10);
        int r = fb.op(20);
        System.out.println(r);
    }
    
    
}

示例二

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

public class Carrying1Test {
    @FunctionalInterface
    interface Fa {
        Fb op(List<Integer> a);
    }
    
    @FunctionalInterface
    interface Fb {
        Fc op(List<Interger> b);
    }
    
    @FunctionalInterface
    interface Fc {
        List<Integer> op(List<Integer> c);
    }
    
    static Fc step2(Fb fb) {
        List<Integer> y = List.of(4, 5, 6);
        return fb.op(y);
    }
    
    static void step3(Fc fc) {
        List<Integer> z = List.of(7, 8, 9);
        List<Integer> result = fc.op(z);
        System.out.println(result);
    }
    
    public static void main(String[] args) {
        step3(step2(step1()));
    }
    
}

高阶函数

所谓高阶,就是指它是其它函数对象的使用者

  • 将通用、复杂的逻辑隐含在高阶函数内
  • 将易变、未定的逻辑放在外部的函数对象中

image-20241007202851624

public class InnerLoop {
	
    public static void main(String[] args) {
        List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7);
        
        // 需求:逆序遍历集合,只想负责元素处理,不改变集合
        hiOrder(list, (value) -> System.out.println(value));
    }
    
    public static void void hiOrder(List<Integer> list, Consumer<Integer> consumer) {
        ListIterator<Integer> iterator = list.listInterator(list.size());
        while (iterator.hasPrevious()) {
            Integer value = iterator.previous();
            consumer.accept(value);
        }
        
        
    }
}

image-20241007202748128

import java.util.LinkedList;

public class BinaryTree {
    
    public record TreeNode(int value, TreeNode left, TreeNode right) {
        public String toString() { return "%d".formatted(value); }
    }
    
    enum Type {
        PRE, IN, POST
    }
    public static void traversal(TreeNode root, Type type, Consumer<TreeNode> consumer) { 
   		// 用来记住回去的路
        LinkedList<TreeNode> stack = new LinkedList<>();
        // 当前节点
        TreeNode curr = root;
        // 记录最近一次处理完的节点
        TreeNode last = null;
        while (curr != null || !stack.isEmpty()) {
            // 左边未走完
            if (curr != null) {
                // 记住来时的路
                stack.push(curr);
                if (type == Type.PRE) {
                    consumer.accept(curr);
                }
                // 下次向左走
                curr = curr.left;
            } else {
                TreeNode peek = stack.peek();
                
                if (peek.right == null) {
                    if (type == Type.IN || type == Type.POST) {
                        consumer.accept(peek);
                    }
                    last = stack.pop();
                } else if (peek.right == last) {
                    if (type == Type.POST) {
                        consumer.accept(peek);
                    }
                    last = stack.pop();
                } else {
                    
                    if (type == Type.POST) {
                        consumer.accept(peek);
                    }
                    curr = peek.right;
                }
            }
        }
        
        
    }
    
    public static void main(String[] args) {
        /* 
        	1
           / \
          2   3
         /   / \ 
        4   5   6
        *
        */
        
        TreeNode root = new TreeNode(
        	new TreeNode(2, new TreeNode(4, null, null), null),
            new TreeNode(3, new TreeNode(5, null, null), new TreeNode(6, null, null))
        );
        
        traversal(root, Type.PRE, System.out::print);
        System.out.println();
        traversal(root, Type.IN, System.out::print);
        System.out.println();
        traversal(root, Type.POST, System.out::print);
        System.out.println();
    }
}

stream

image-20241007205851325

import java.util.Collection;
import java.util.List;

public class SimpleStream<T> {
    public static void main(String[] args) {
        List<Integer> list = List.of(1, 2, 3, 4, 5);
        
        SimpleStream.of(list)
            		.filter(x -> (x & 1) == 1) 
            		.map(x -> x * x)
            		.forEach(System.out::println);
    }
    
    public static <T> SimpleStream<T> of(Collection<T> collection) {
        return new SimpleStream<>(Collection);
    }
    
    private Collection<T> collection;
    
    private SimpleStream(Collection<T> collection) {
        this.collection = collection;
    }
    
    public SimpleStream filter(Predicate<T> predicate) {
        List<T> result = new ArrayList<>();
        for (T t : collection) {
            if (predicate.test(t)) {
                result.add(t);
            }
        }
        
        return new SimpleStream<>(result);
    }
    
    public <U> SimpleStream<U> map(Function<T, U> function) {
        List<U> result = new ArrayList<>();
        for (T t : collection) {
            U u = function.apply(t);
            result.add(U);
        }
        
        return new SimpleStream<>(result);
    }
    
    public void forEach(Consumer<T> consumer) {
        for (T t : collection) {
			consumer.accept(t);
        }
    }
}

image-20241007212646149

import java.util.Collection;
import java.util.List;

public class SimpleStream<T> {
    public static void main(String[] args) {
        List<Integer> list = List.of(1, 2, 3, 4, 5);
        
        HashSet<Integer> collect = SimpleStream.of(list)
            						.collect(HashSet::new, HashSet::add); // HashSet::add (set, t) -> set.add(t)
        System.out.println(collect);
        
        StringBuilder collect2 = SimpleStream.of(list).collect(StringBuilder::new, StringBuilder::append);
        System.out.println(collect2);
        
        SimpleStream.of(list).collect(() -> new StringJoiner("-"), (joiner, t) -> joiner.add(String.valueOf(t)));
        
        SimpleStream.of(list)
            		.map(t->String.valueOf(t))
            		.collect(()->new StringJoiner("-"), StringJoiner::add);
        System.out.println(collect3);
        
        // (StringJoiner, Integer) -> void
        // (StringJoiner, CharSequence) -> void
        
        
        SimpleStream.of(list)
            		.filter(x -> (x & 1) == 1) 
            		.map(x -> x * x)
            		.forEach(System.out::println);
        
        System.out.println(SimpleStream.of(list).reduce(0, Integer::sum));
        System.out.println(SimpleStream.of(list).reduce(Integer.MAX_VALUE, Math::min));
        System.out.println(SimpleStream.of(list).reduce(Integer.MIN_VALUE, Math.max));
        
    }
    
    public static <T> SimpleStream<T> of(Collection<T> collection) {
        return new SimpleStream<>(Collection);
    }
    
    private Collection<T> collection;
    
    private SimpleStream(Collection<T> collection) {
        this.collection = collection;
    }
    
    // C 代表容器类型,supplier 用来创建容器
	public <C> C collect(Supplier<C> supplier, BiConsumer<C, T> consumer) {
        C c = supplier.get(); //创建了容器
		for (T t : collection) {
            consumer.accept(c, t); // 向容器中添加元素
        }
        
        return c;
    }
    
    // 新增
    public T reduce(T o, BinaryOperator<T> operator) {
        T p = o;
        
        for (T t : collection) { // t是本次遍历的元素
            p = operator.apply(p, t); // 累加器
        }
        
        return p;
    }
    
    public SimpleStream filter(Predicate<T> predicate) {
        List<T> result = new ArrayList<>();
        for (T t : collection) {
            if (predicate.test(t)) { // 过滤器
                result.add(t);
            }
        }
        
        return new SimpleStream<>(result);
    }
    
    public <U> SimpleStream<U> map(Function<T, U> function) {
        List<U> result = new ArrayList<>();
        for (T t : collection) {
            U u = function.apply(t);
            result.add(U);
        }
        
        return new SimpleStream<>(result);
    }
    
    public void forEach(Consumer<T> consumer) {
        for (T t : collection) {
			consumer.accept(t); // 遍历
        }
    }
    
}

image-20241007223754622

public class SimpleStream<T> {
    public static void main(String[] args) {
        List<Integer> list = List.of(1, 2, 3, 4, 5, 1, 2, 3);
        /*
        	key			value
        	1             1
        	2             2
        	3             2
        	4             1
        	5             1
        */
        
        HashMap<Integer, Integer> collect = SimpleStream.of(list)
            .collect(HashMap::new, (map, t) -> {
                if (!map.containsKey(t)) {
                    map.put(t, 1);
                } else {
                    Integer v = map.get(t);
                    map.put(t, v + 1);
                }
            });
        System.out.println(collect);
        
        HashMap<Integer, AtomicInteger> collect2 = SimpleStream.of(List)
            .collect(HashMap::new, (map, t) -> map.computeIfAbsent(t, k -> new AtomicInteger()).getAndIncrement());
        System.out.println(collect2);
        
    }
}

三. Stream API

image-20241007231429134

filter过滤 Predicate

public class FilterTest {
    public static void main(String[] args) {
        Stream.of (
                new Fruit(cname: "草莓", name: "Strawberry", category: "浆果", color: "红色"),
                new Fruit(cname: "桑葚", name: "Mulberry", category: "浆果", color: "紫色"),
                new Fruit(cname: "杨梅", name: "Waxberry", category: "浆果", color: "红色"),
                new Fruit(cname: "核桃", name: "Walnut", category: "坚果", color: "棕色"),
                new Fruit(cname: "花生", name: "Peanut", category: "坚果", color: "棕色"),
                new Fruit(cname: "蓝莓", name: "Blueberry", category: "浆果", color: "蓝色")
        )
            .filter(f->f.category().equals("浆果")) // && f.color().equals("蓝色")
            .filter(f->f.color().equals("蓝色"))
            .forEach(System.out::println);
    }
    
    // Java 17新特性
    record Fruit(String cname, String name, String category, String color) {
        
    }
}

image-20241007232348630

public class FilterTest {
    public static void main(String[] args) {
        Stream.of (
                new Fruit(cname: "草莓", name: "Strawberry", category: "浆果", color: "红色"),
                new Fruit(cname: "桑葚", name: "Mulberry", category: "浆果", color: "紫色"),
                new Fruit(cname: "杨梅", name: "Waxberry", category: "浆果", color: "红色"),
                new Fruit(cname: "核桃", name: "Walnut", category: "坚果", color: "棕色"),
                new Fruit(cname: "花生", name: "Peanut", category: "坚果", color: "棕色"),
                new Fruit(cname: "蓝莓", name: "Blueberry", category: "浆果", color: "蓝色")
        )
        .map(f->f.cname()+"酱") // Stream<String>
        .forEach(System.out::println);
    }
    
    // Java 17新特性
    record Fruit(String cname, String name, String category, String color) {
        
    }
}

image-20241007232741938

public class FilterTest {
    public static void main(String[] args) {
        Integer[][] array2D = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9},
        };
    
        Arrays.stream(array2D)
            	.flatMap(array -> Arrays.stream(array))
            	.forEach(System.out::println);
        
    // Java 17新特性
    record Fruit(String cname, String name, String category, String color) {
        
    }
}

image-20241007233412077

import java.util.List;

public class BuildStreamTest {
    public static void main(String[] args) {
        
        // 1. 从集合构建
        Set.of(1, 2, 3).stream().forEach(System.out::println);
        Map.of("a", 1, "b", 2).entrySet().stream().forEach(System.out::println);
        
        int[] array = {1, 2, 3}
        Arrays.stream(array).forEach(System.out::println);
        
        // 3. 从对象构建
        Stream.of(1, 2, 3, 4, 5).forEach(System.out::println);
        
        
    }
}

image-20241007233959266

public class ConcatSplitTest {
    public static void main(String[] args) {
        // 1. 合并
        Stream<Integer> s1 = Stream.of(1, 2, 3);
        Stream<Integer> s2 = Stream.of(4, 5);
        
        Stream<Integer> concat = Stream.concat(s1, s2);
        concat.forEach(System.out::println);
        /*
        	2. 截取 - 直接给出截取位置
        	skip(long n)  跳过 n 个数据, 保留剩下的
        	limit(long n) 保留 n 个数据,剩下的不要
        */
        
//        concat.skip(2).forEach(System.out::print);
        concat.limit(2).forEach(System.out::print);
        
        /**
        	takeWhile(Predicate p)  条件成立保留,一旦条件不成立,剩下的不要
        	dropWhile(Predicate p)  条件成立舍弃,一旦条件不成立,剩下的保留
        */
        
        concat.takeWhile(x -> x < 3).forEach(System.out::print);
        concat.dropWhile(x -> x < 3).forEach(System.out::print);
    }
}

image-20241007234741879

public class GenerateTest {
    public static void main(String[] args) {
        // 1. IntStream.range
        
        IntStream.rang(1, 10).forEach(System.out::println);
        IntStream.rangeClosed(1, 1).forEach(System.out::println);
        
        // 2. IntStream.iterate 生成 1 3 5 7 9 ... 奇数序列 可以根据上一个元素值来生成当前元素
        InStream.iterator(1, x -> x + 2).forEach(System.out::println);	
        InStream.iterator(1, x -> x <= 9, x -> x + 2).forEach(System.out::println);
        
        // IntStream.generate
        IntStream.generate(() -> ThreadLocalRandom.current().nextInt(100)).limit(5).forEach(System.out::println);
        
        ThreadLocalRandom.current().ints(streamSize: 5, randomNumberOrigin: 0, randomNumber: 100).forEach(System.out::println);
    }
}

image-20241008091700932

import java.util.stream.IntStream;

public class FindTest {
    public static void main(String[] args) {
        IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6);
        
        // 找到第一个偶数
        System.out.println(stream.filter(x -> (x & 1) == 0).findFirst().orElse(-1));
        
        stream.filter(x -> (x & 1) == 0).findFirst().ifPresent((x)->System.out.println(x));
        // 找到任意一个偶数
        stream.filter(x -> (x & 1) == 0).findAny().ifPresent((x) -> System.out.println(x));
        
        // 见名知意
        System.out.println(stream.anyMatch(x -> (x&1) == 0));
        System.out.println(stream.allMatch(x -> (x & 1)) == 0);
        System.out.println(stream.noneMatch(x -> (x & 1)) == 0);
        
        	
    }
}

去重与排序

public class SortTest {
    public static void main(String[] args) {
        // 去重
        IntStream.of(1, 2, 3, 1, 2, 3, 3, 4, 5)
            	  .distince()
            	  .forEach(System.out::println);
        
        // 排序
        Stream.of (
        			// 排序
                new Hero(name: "令狐冲", strength: 90),
                new Hero(name: "风清扬", strength: 98),
                new Hero(name: "独孤求败", strength: 100),
                new Hero(name: "方证", strength: 92),
                new Hero(name: "东方不败", strength: 98),
                new Hero(name: "冲虚", strength: 90),
                new Hero(name: "向问天", strength: 88),
                new Hero(name: "任我行", strength: 92),
                new Hero(name: "不戒", strength: 88)
        )
            // 重要:简洁但可能存在溢出问题。
            .sorted((a, b) -> a.strength() - b.strength()) // a.strenght < b.strength ? -1 : a.strength() == b.strength() ? 0 : 1
            // .sorted((a, b) -> Integer.compare(a.strength(), b.strength()))
            // .sorted((Comparator.comparingInt(h -> h.strength()))
             .sorted(Comparator.comparingInt(Hero::strength).reverse().thenComparingInt(h->h.name.length()))         
            .forEach(System.out::println);
        
        // Hero::strength <==> (h) -> h.strength();
        record Hero(String name, int strength) {
            
        }
    }
}

reduce

import java.util.stream.Stream;

/*
	简化:两两合并,只剩下一个
	适合:最大值,最小值,求和,求个数...
	.reduce((p, x) -> r) p 上次的合并结果,x 当前元素, r 本次合并结果
	.reduce(init, (p, x) -> r)
	.reduce(init, (p, x) -> r, (r1, r2) -> r)
*/ 
public class ReduceTest {
    record Hero(String name, int strength) { ... }

    public static void main(String[] args) {
        Stream<Hero> result = Stream.of (
            new Hero(name: "令狐冲", strength: 90),
            new Hero(name: "风清扬", strength: 98),
            new Hero(name: "独孤求败", strength: 100),
            new Hero(name: "方证", strength: 92),
            new Hero(name: "东方不败", strength: 98),
            new Hero(name: "冲虚", strength: 90),
            new Hero(name: "向问天", strength: 88),
            new Hero(name: "任我行", strength: 92),
            new Hero(name: "不戒", strength: 88)
        );
        
        // 1.求武力最高的 hero
        Optional<Hero> result = stream.reduce((h1, h2) -> h1.strength() > h2.strength() ? h1 : h2)
		
        Hero result = stream.reduce(new Hero("-", -1), (h1, h2) -> h1.strength() > h2.strength() ? h1 : h2);
        System.out.println(result);
        
        // 求高手总数
        System.out.println(stream.map(h -> 1).reduce(0, (a, b) -> a + b));
        
        System.out.println(stream.count());
        stream.max(Comparator.comparingInt(Hero::strength));
        stream.min(Comparator.comparingInt(Hero::strength));
        
        stream.mapToInt(Hero::strength).sum());
        stream.mapToInt(Hero::strength).average());
    }
}

收集器

image-20241008101936930

import java.util.stream.Stream;

public class C11CollectTest {
    record Hero(String name, int strength) { ... }
    /*
    	收集:将元素收集入容器
    	.collect(() -> c, (c, x) -> void, ?)
    	() -> c			创建容器 c
    	(c, x) -> void  将元素 x 加入 容器 c
    */
    
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("令狐冲", "风清扬", "孤独求败", "方证", "东方不败","冲虚","向问天","任我行","不戒");
        // 1.收集到 List
        List<String> result = stream.collect(() -> new ArrayList<>(), (list, x) -> list.add(x), (a, b) -> { });
        /*
            ArrayList::new 			() -> new ArrayList()
            ArrayList::add 			(list, x) -> list.add(x)
            能等价就等价看自己的风格或要求
        */    
        // 缺点:不太方便调试
        List<String> result = stream.collect(ArrayList::new, ArrayList::add, (a, b) -> { });
        
        Set<String> result = stream.collect(LinkeeHashSet::new, Set::add, (a, b) -> { });
        
        Map<String, Integer> result = stream.collect(HashMap::new, (map, x) -> map.put(x, 1), (a, b) -> { });
        
        // 流空,不实现
        stream.collect(StringBuilder::new, StringBuilder::append, (a, b) -> { });
        
        stream.collect(() -> new StringJoiner(","), StringJoiner:add, (a, b) -> { });
    }
}

image-20241008105156898

image-20241008111021453

import java.util.stream.Stream;

// 收集器 Collectors
public class C11CollectTest {
    record Hero(String name, int strength) { ... }
    /*
    	收集:将元素收集入容器
    	.collect(() -> c, (c, x) -> void, ?)
    	() -> c			创建容器 c
    	(c, x) -> void  将元素 x 加入 容器 c
    */
    
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("令狐冲", "风清扬", "孤独求败", "方证", "东方不败","冲虚","向问天","任我行","不戒");
        // 1.收集到 List
        List<String> result = stream.collect(() -> new ArrayList<>(), (list, x) -> list.add(x), (a, b) -> { });
        /*
            ArrayList::new 			() -> new ArrayList()
            ArrayList::add 			(list, x) -> list.add(x)
            能等价就等价看自己的风格或要求
        */    
        // 缺点:不太方便调试
        List<String> result = stream.collect(ArrayList::new, ArrayList::add, (a, b) -> { }); 
        List<String> result = stream.collect(Collectors.toList());
        
        Set<String> result = stream.collect(LinkeeHashSet::new, Set::add, (a, b) -> { });
        Set<String> result = stream.collect(Collectors.toSet());
        
        Map<String, Integer> result = stream.collect(HashMap::new, (map, x) -> map.put(x, 1), (a, b) -> { });
        Map<String, Integer> result = stream.collect(Collectors.toMap(x -> x, x -> 1));
        
        // 流空,不实现
        stream.collect(StringBuilder::new, StringBuilder::append, (a, b) -> { });
        stream.collect(Collectors.joining;
        
        stream.collect(() -> new StringJoiner(","), StringJoiner:add, (a, b) -> { });
        stream.collect(Collectors.joining(","));
                       
        /*
            3:new ArrayList(["令狐冲", “风清扬", “向问天",“任我行"])
            4:new ArrayList(["独孤求败","东方不败"])
            2: new ArrayList(["方证",“冲虚",“不戒"])
        */
        Map<Integer, List<String>> result = stream.collect(Collectors.groupingBy(x -> x.length(), Collectors.toList()));
                       
        for (Map.Entry<Integer, List<String>> e : result.entrySet()) {
                System.out.println(e);
        }
        
       /**
       	1. mapping(x->y, dc) 需求:根据名字长度分组,分组后组内只保留他们的武力值
            new Hero("令狐冲", 90) -> 90
            dc 下游收集器 down collector 
       */
        Map<Integer, List<Integer>> collect = stream.collect (
        	groupingBy(h -> h.name().length(), mapping(h -> h.strength(), toList())));
                       
        for (Map.Entry<Integer, List<Integer>> e : collect.entrySet()) {
            System.out.println(e);
        }
        
        /*
        * 2. filtering(x -> boolean, dc) 需求:根据名字长度分组,分组后组内过滤掉武力小于 90 的
        */
        
        // 在分组收集的过程中,执行过滤
        Map<Integer, List<Hero>> collect1 = stream.collect (
        	groupingBy(h -> h.name().length(), filtering(h -> h.strength() >= 90, toList()));
        )
        
        // 先过滤,再来分组收集
        Map<Integer, List<Hero>> collect1 = stream.filter(h -> h.strength() >= 90)
                       			.collect(groupingBy(h -> h.name().length(), toList()));
                       
        for (Map.Entry<Integer, List<Hero>> e : collect1.entrySet()) {
            System.out.println(e);
        }
           
        /**
        * 3. flatMapping(x -> substream, dc)          需求:根据名字长度分组,分组后组内保留人名,并且人名切分成单个字符
        */
         // Character::toString (x) -> x.toString(); 
        "令狐冲".chars().mapToObj(Character.toString.forEach(System.out::println);
        
        stream.collect(groupingBy(h -> h.name().length(), flatMapping(h->h.name().chars().mapToObj(Character::toString), toList())));
                               
                               
        for (Map.Entry<Integer, List<String>> e : collect.entrySet()) {
            System.out.println(e);
        }
     
        /*
        * 4. counting() 需求:根据名字长度分组,分组后求每组个数
        */
        Map<Integer, Long> collect = stream.collect(groupingBy(h -> h.name().length(), count()));
        for (Map.Entry<Integer, Long> e : collect.entrySet()) {
            System.out.println(e);
        }
                               
        /*
        * minBy((a, b) -> int) 需求:根据名字长度分组,分组后求每组武功最低的人
        * maxBy((a, b) -> int) 需求:根据名字长度分组,分组后求每组武功最高的人
        */
        stream.collect(groupingBy(h -> h.name().length(), maxBy(Comparator.comparingInt(Hero::strength))));
         
        /*
        * 7. summingInt(x -> int)       需求:根据名字长度分组,分组后求每组武力和
        * 8. averagingDouble(x -> double)  需求:根据名字长度分组,分组后求每组武力平均值
        *
        * stream.collect(groupingBy(h -> h.name().length(), averagingDouble(h -> h.strength())));
        */
        for (Map.Entry<Integer, Optional<Hero>> e : collect.entrySet()) {
            System.out.println(e);
        }
                               
        
        /*
        * 9. reducing(init, (p, x) -> r)
        */
         stream.collect(groupingBy(h -> h.name().length(), mapping(h -> h.strength(), reducing(0, (p, x) -> p + x))));
         
    }
}

基本流

image-20241008160903373

image-20241008161139270

import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.uyil.stream.LongStream;
import java.util.stream.Stream;

public class C14Effective {
    /*
    	三种基本流
    */
    public static void main(String[] args) {
        IntStream a = IntStream.of(97, 98, 99);
        LongStream b = LongStream.of(1L, 2L, 3L);
        DoubleStream c = DoubleStream.of(1.0, 2.0, 3.0);
        
        Stream<Integer> d = Stream.of(1, 2, 3);
        
        a.mapToObj(Character::toString).forEach(System.out::println);
        
        IntSummaryStatistics stat = a.summaryStatistics();
        System.out.println(stat.getSum());
        System.out.println(stat.getCount());
        System.out.println(stat.getMax());
        System.out.println(stat.getMin());
        System.out.println(stat.getAverage());
        
        Stream<Hero> stream = Stream.of(
        		new Hero("令狐葱", 90),
            	new Hero("风清扬"98)
        );
            
        stream.mapToInt(Hero::strength).forEach(System.out::println);
        
    }
}

流的特性

import java.util.stream.Stream;

public class C15Summary {
    public static void main(String[] args) {
        /**
        * 掌握 Stream 流的特性
        * 1. 一次使用
        * 2. 两类操作(中间操作 lazy 懒惰, 终结操作 eager 迫切)
        */
        
        Stream<Integer> s1 = Stream.of(1, 2, 3, 4, 5);
        
        s1
            .map(x -> x + 1)
            .filter(x -> x <= 5)
            .forEach(x -> System.out::println);
        
    }
}

image-20241008162707310

image-20241008162741576

image-20241008163214599

image-20241008163345241

stream 并行

import static java.util.stream.Collectors.toList;

// 并行流
public class C16Parallel {
    public static void main(String[] args) {
        /* ... */
        
        List<Integer> collect = Stream.of(1, 2, 3, 4)
            					.parallel()
            					.collect(Collector.of (
                                	() -> new ArrayList(), // 如何创建容器
                                    (list, x) -> list.add(x), // 如何向容器添加数据
                                    (list1, list2) -> {
                                    	list1.addAll(list2);
                                        return list1;
                                    },    // 如何合并两个容器的数据
                                   list -> list      // 收尾
                           // 特性:并发,是否需要收尾,是否要保证收集顺序   (默认)容器不支持并发,需要收尾,要保证收集顺序
                                ));
        
        System.out.println(collect);
    }
    
    private static String simple() { }
}
import static java.util.stream.Collectors.toList;

// 并行流
public class C16Parallel {
    public static void main(String[] args) {
        /* ... */
        
        List<Integer> collect = Stream.of(1, 2, 3, 4)
            		.parallel()
            		.collect(Collertor.of)(
        			() -> {
                        System.out.printf("%-12s %s%n", simple(), "create"); // 1.如何创建容器
                        return new ArrayList<Integer>();
                    },
        			(list, x) -> {
                        List<Integer> old = new ArrayList<>(list);
                        list.add(x);
                        System.out.printf("%-12s %s.add(%d)=>%s%n", simple(), old, x, list);
                    },														// 2. 如何向容器添加数据
            		(list1, list2) -> {
                        List<Integer> old = new ArrayList<>(list1);
                        list1.addAll(list2);
                        System.out.println("%-12s %s.add(%s)=>%s%n", simple(), lod, list2, list3);
                        return list1;
                    }														// 3.如何合并两个容器的数据
            		list -> {
                        System.out.printf("%-12s finish: %s=>%s%n", simple(), list, list);
                        return list;
                    }													// 4.收尾
            		// 5. 特性:容器不支持并发,需要收尾,要保证收集顺序
            		
        	)
            System.out.println(e);
    }
    
    private static String simple() { }
}

image-20241008171250518

public class C16Parallel {
    public static void main(String[] args) {
        /*
        * 1. 数据量问题:数据量大时才建议用并行流
        * 2. 线程会无限增加吗:跟 cpu 能处理的线程数相关
        * 3. 收尾的意义: 转不可变集合,StringBuilder 转 String
        * 4. 是否线程安全: 不会有线程安全问题
        * 5. 特性
        *		是否需要收尾(默认收尾),
        		是否需要保证顺序(默认保证)
        		容器是否支持并发(默认不支持)
        		
        		到达选择哪一种?
        			A. Characteristics.CONCURRENT + Characteristics.UNORDERED + 线程安全容器
                    B. 默认 + 线程不安全容器
        */
        
        List<Integer> collect = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
            		.parallel()
            		.collect(Collertor.of(
        			() -> {
                        System.out.printf("%-12s %s%n", simple(), "create"); // 1.如何创建容器
                        return new ArrayList<Integer>();
                    },
        			(list, x) -> {
                        List<Integer> old = new ArrayList<>(list);
                        list.add(x);
                        System.out.printf("%-12s %s.add(%d)=>%s%n", simple(), old, x, list);
                    },														// 2. 如何向容器添加数据
            		(list1, list2) -> {
                        List<Integer> old = new ArrayList<>(list1);
                        list1.addAll(list2);
                        System.out.println("%-12s %s.add(%s)=>%s%n", simple(), lod, list2, list3);
                        return list1;
                    }														// 3.如何合并两个容器的数据
            		list -> {
                        System.out.printf("%-12s finish: %s=>%s%n", simple(), list, list);
                        return Collections.unmodifiableList(list);
                    }													// 4.收尾
            		// 5. 特性:容器不支持并发,需要收尾,要保证收集顺序
            		, Collector.Characteristics.IDENTITY_FINISH			// 不需要收尾Collector.Characteristics.UNORDERED				// 不需要保证顺序
                    , Collector.Characteristics.CONCURRENT				// 容器需要支持并发
        	)
                             
            System.out.println(e);
            collect.add(100);
    }
    
    private static String simple() { }

Stream 流的性能

// 性能: 求和 JMH
public class T01Sum {
    @State(Scope.Benchmark)
    public static class MyState { ... }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int primitive(MyState state) {
        int sum = 0;
        for (int number : state.numbers) {
            sum += number;
        }
        return sum;
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AveragetTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int boxed(MyState state) { 
    	int sum = 0;
        for (Integer i : state.numberList) {
            sum += i;
        }
        return sum;
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int stream(MyState state) {
        return state.numberList.stream().reduce(0, (a, b) -> a + b);
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int intStream(MyState state) {
        return IntStream.of(state.numbers).sum();
    }
    
    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
            	.include(TO1Sum.class.getSimpleName())
            	.forks(1)
            	.build();
        
        new Runner(opt).run();
        
    }
}

image-20241008174801962

image-20241008174824092

pubilc class T02Parallel {
    static final int n = 1000000;
    
    @State(Scope.Benchmark)
    pubilc static class MyState {
        int[] numbers = new int[n];
        {
            for (int i = 0; i < n; i++) {
                numbers[i] = ThreadLocalRandom.current().nextInt(10000000);
            }
        }
    }
    
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int primitive(MyState state) {
        int max = 0;
        for (int number : state.numbers) {
            if (number > max) {
                max = number;
            }
        }
        
        return max;
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int sequence(MyState state) {
        return IntStream.of(state.numbers).max().orElse(0);
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int parallel(MyState state) {
        return IntStram.of(state.number).parallel().max().orElse(0);
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int custom(Mystate state) throws ExecutionException, InterruptedException {
        int[] numbers = state.numbers;
        int step = n / 10;
        ArrayList<Future<Integer>> result = new ArrayList<>();
        try (ExecutorService service = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int j = 0; j < n; j += step) {
                int k = j;
                result.add(service.submit(() -> {
                    int max = 0;
                    for (int i = k; i < k + step; i++) {
                        if (numbers[i] > max) {
                            max = numbers[i];
                        }
                    }
                    
                    return max;
                }));
            }
            
            System.out.println(result.size());
			int max = 0;
            for (Future<Integer> future : result) {
                if (future.get() > max) {
                    max = future.get();
                }
            }
            
            return max;
        }
    }
}

image-20241008191153029

image-20241008191332644

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

public class T03Concurrent {
    
    static final int n = 1000000;
    
    @State(Scope.Benchmark)
    public static class MyState {
        int[] numbers = new int[n];
        {
            for (int i = 0; i < n; i++) {
                numbers[i] = ThreadLocalRandom().current().nextInt(n / 10);
            }
        }
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public Map<Integer, Integer> loop1(MyState state) {
        Map<Integer, Integer> map = new HashMap<>();
        
        for (int number : state.numbers) {
            map.merge(number, 1, Integer::sum);
        }
        return map;
    }
    
  	@Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public Map<Integer, Integer> loop1(MyState state) {
        Map<Integer, Integer> map = new HashMap<>();
        
        for (int number : state.numbers) {
            map.computeIfAbsent(number, k -> new AtomicInteger()).getAndIncrement();
        }
        return map;
    }  
    
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public Map<Integer, Long> sequence(MyState state) {
        return Arrays.stream(state.numbers).boxed()
            	.collect(groupingBy(Function.identity(), counting()));
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public Map<Integer, Long> parallelNoConcurrent(MyState state) {
        return Arrays.stream(state.numbers).boxed()
            	.parallel()
            	.collect(groupingBy(Function.identity(), counting()));
    }
    
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public ConcurrentMap<Integer, Long> parallelConcurrent(MyState state) {
        return Arrays.stream(state.numbers).boxed()
            	.parallel()
            	.collect(groupingByConcurrent(Function.identity(), counting()));
    }
    
    public static void main(String[] args) throws RunnerException, ExecutionException, InterruptedException {
        
    }
}

image-20241008192804304

image-20241008192959684

四.实际应用统计、异步、框架、并行、事件

统计

static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
    try (Stream<String> lines = Files.lines(Path.of("./data.txt"))) {
        lines.skip(1).limit(5).forEach(line->System.out.println(line));
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
每月的销售量
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
    try (Stream<String> lines = Files.lines(Path.of("./data.txt"))) {
       long start = System.currentTimeMillis();
        Map<YearMonth, Long> collect = lines.skip(1)
            						.map(line -> line.split(","))
            						.collect(groupingBy(array -> YearMonth).from(formatter.parse(array[TIME]), TreeMap::new, counting()));
        
        System.out.println("花费" + (System.currentTimeMillis() - start));
        
        for (Map.Entry<YearMoth, Long> e : collect.entrySet()) {
            System.out.println(e);
        }
        
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
统计销量最高的月份
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
   try (Stream<String> lines = Files.lines(Path.of("./data.txt"))) {
     	lines.skip(1)
            	.map(line -> line.split(","))
            	.collect(groupingBy(array -> YearMonth.from(formatter.parse(array[TIME])), counting()))
            	.entrySet().stream()
            	// .max(Comparator.comparingLong(e -> e.getValue()));
            	.max(Map.Entry.comparingByValue())
            	.ifPresent(x -> System.out.println(x));
   } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
销量最高的商品
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
	case3();
}
private static void case3() {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
        lines.skip(1)
            	.map(line->line.split(","))
            	.collect(groupingBy(array->array[PRODUCT_ID], counting()))
            	.entrySet().stream()
            	.max(Map.Entry.comparingByValue())
            	.ifPresent(System.out::println);
        
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
下单最多的前10用户
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
	case4();
}
private static void case4() {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
        lines.skip(1)
            	.map(line -> line.split(",")
                .collect(groupingBy(array -> array[USER_ID], counting));
         
        for (Map.Entry<String, Long> e : collect.entrySet()) {
            System.out.println(e);
        }
         
         collect.entrySet().stream()
                .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                .limit(10)
                .forEach(System.out::println);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
最小堆
static class MyQueue<E> extends PriorityQueue<E> {
    private int max;
    public MyQueue(Comparator<? super E> comparator, int max) {
        super(comparator);
        this.max = max;
    }
    
    @Override
    public boolean offer(E e) {
        boolean r = supper.offer(e);
        if (this.size()  > max) {
            this.poll();
        }
        
        return r;
    }
  
}
private static void case4() {
    try (Stream<String> lines = Files.lines(Path.of("./data.txt"))) {
        Map<String, Long> collect = lines.skip(1)
        .map(line -> line.split(","))
        .collect(groupingBy(array -> array[USER_ID], counting()));
        
        // 小顶推
        MyQueue<Map.Entry<String, Long>> map = collect.entrySet().stream()
            .collect (
                () -> new MyQueue<Map.Entry<String, Long>(Map.Entry.comparingByValue())
                (queue, x) -> queue.offer(x),
                (q1, q2) -> q1.addAll(q2)
        );
        
        while(!queue.isEmpty()) {
            System.out.println(queue.poll());
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
每个地区下单最多的用户
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
	case5();
}
private static void case5() {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
       Map<String, Map<String, Long>> collect = lines.skip(1)
           			.map(line -> line.split(","))
           			.collect(groupingBy(array -> array[USER_GEGION], groupingBy(array -> array[USER_ID], counting())));
        
        collect.entrySet().stream.map(e -> Map.entry(
        			e.getKey(),
            		e.getValue().entrySet().stream()
            			.max(Map.Entry.comparingByValue())
        ))
            .forEach(System.out::println);
        
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
每个地区下单最多的前3用户
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
	case5();
}
private static void case5() {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
       Map<String, Map<String, Long>> collect = lines.skip(1)
           			.map(line -> line.split(","))
           			.collect(groupingBy(array -> array[USER_GEGION], groupingBy(array -> array[USER_ID], counting())));
        
        collect.entrySet().stream.map(e -> Map.entry(
        			e.getKey(),
            //		e.getValue().entrySet().stream()
            //			.sorted(Map.Entry.comparingByValue().reverse())
            //			.limit(3)
            //			.collect(toList())
            		e.getValue().entrySet().stream()
            			.collect (
                        		() -> new MyQueue<Map.Entry<String, Long>> (Map.Entry.comparingByValue(), 3)
                            	MyQueue::offer
                            	MyQueue::addAll
                        )
        ))
            .forEach(System.out::println);
        
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
按一级类别统计销量
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
	case6();
}
static String firstCategory(String[] array) {
    String c = array[CATEGORY_CODE];
    int idx = c.indexOf(".");
    return c.substring(0, idx);
}
private static void case6() {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
       Map<String, Long> collect = lines.skip(1)
           				.map(line -> line.split(","))
           				.filter(array -> !array[CATEGORY_CODE].isEmpty())
           				.collect(groupingBy(TestData::firstCategory, TreeMap::new, counting()));
        
        for (Map.Entry<String, Long> e : collect.entrySet()) {
            System.out.println(e);
        }
        
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
按区间统计销量
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
	case7();
}
static String priceRange(Double price) {
    if (price < 100) {
        return "[0, 100)";
    } else if (price >= 100 && price < 500) {
        return "[100, 500)"
    } else if (price >= 500 && price < 1000) {
        return "[500, 1000)";
    } else {
        return "[1000, 无穷)";
    }
}
private static void case6() {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
       lines.skip(1)
           	.map(line -> line.split(","))
            .map(array->Double.valueOf(array[PRICE]))
            .collect(groupingBy(TestData::priceRange, counting()));
        
        // 打印集合 略
           
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
不同年龄段女性下不同类别订单
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

public static void main(String[] args) {
	case8();
}
static String ageRange(Double price) {
    int age = Double.valueOf(array[USER_AGE]).intValue();
    if (age < 18) {
        return "[0, 18)";
    } else if (age < 30) {
        return "[18, 30)";
    } else if (age < 50) {
        return "[30, 50)";
    } else {
        return "[50, 无穷)"
    }
}
private static void case8() {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
       lines.skip(1)
           	.map(line -> line.split(","))
            .filter(array->array[USER_SEX].equals("女"))
        	.filter(array-> array[CATEGORY_CODE].isEmpty())
            .collect(groupingBy(TestData::ageRange, 
                                groupingBy(TestData::firstCategory, TreeMap::new, counting())));
        
        for (Map.Entry<String, Map<String, Long>> e1 : map.entrySet()) {
            for (Map.Entry<String, Long> e2 : e1.getValue().entrySet()) {
                System.out.println("%-12s%-15s%d%n", e1.getKey(), e2.getKey(), e2.getValue());
            }
        }
        
        
        // 打印集合 略
           
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

异步处理

static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

static Logger logger = LoggerFactory.getLogger("Test");

// 1. 显式使用了线程池
// 2. 函数对象嵌套使用,可读行差
public static void main(String[] args) {
	logger.info("开始统");
    // monthlySalesReport();
    new Thread()->monthlySalesReport().start(); // 异步代码调用
    logger.info("执行其他操作");
    /*
    	目标:将处理结果的逻辑放在 monthlySalesReport 之外
    	做法1:将结果作为方法的返回值返回
    	做法2:将处理结果的逻辑作为函数对象传递给方法
    */
    try (ExcutorService service = Executors.newFixedThreadPool(3)) {
        logger.info("开始统计");
        service.submit(()-> {
            monthlySalesReport((map) -> {
                logger.info(e.toString());
            });
        });
        logger.info("执行其他操作");
    }
    
}

private static void monthlySalesReport(Counsumer<Map<YearMonth, Long>> consumer) {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
       		Map<YearMonth, Long> map = lines.skip(1)
                			.map(line -> line.split(","))
                			.collect(groupingBy(array -> YearMonth.from(formatter.parse(array[TIME], TreeMap::new, counting())));
                  
          return collect;                           
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
异步优化
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletebleFuture;

public class C03CompletableFutureTest {
    static Logger logger = loggerFactory.getLogger("Test");
    
    public static void main(String[] args) {
        // 1. 异步执行
        CompletableFuture.runAsync()     // 在任务不需要返回结果时
        CompletableFuture.supplyAsync() // 在任务需要处理结果时
            
            
         CompletableFuture.runAsync(() -> logger.info("异步操作1"));   
         CompletableFuture.supplyAsync(() -> {
             logger.info("异步操作2");
             return "结果";
         }).thenApply(r -> r + "转换后")
             .thenAccept(r -> logger.info(r));
        
        System.in.read(); // 不让主线程立刻结束
        
        
         // 2.处理异步任务的结果
         /*
          thenApply(Function)
          thenApplyAsync
          thenAccept(Consumer)
          thenAcceptAsunc(Consumer)
         */
        
        
    }
}
static final int INDEX = 0;
static final int TIME = 1;
static final int ORDER_ID = 2;
static final int PRODUCT_ID = 3;
static final int CATEGORY_ID = 4;
static final int CATEGORY_CODE = 5;
static final int BRAND = 6;
static final PRICE = 7;
static final int USER_ID = 8;
static final int USER_AGE = 9;
static final int USER_SEX = 10;
static final int USER_REGION = 11;
static final int DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM--dd HH:mm:ss z");

static Logger logger = LoggerFactory.getLogger("Test");

// 1. 显式使用了线程池
// 2. 函数对象嵌套使用,可读行差
public static void main(String[] args) {
	
   CompletableFuture
       	.supplyAsync(() -> monthlySalesReport())
    	.thenAccept(map -> {
            for (Map.Entry<YearMonth, Long> e : map.entrySet()) {
                logger.info(e.toString());
            }
        });
    
    System.in.read();
    
    try (ExcutorService service = Executors.newFixedThreadPool(3)) {
        logger.info("开始统计");
        CompletableFuture
            	.supplyAsync(() -> monthlySalesReport)
            	.thenAccept(map -> {
                    for (Map.Entry<YearMonth, Long> e : map.entrySet()) {
                        logger.info(e. toString());
                    }
                });
        
        logger.info("执行其他操作");
        System.in.read();
    }
    
}

private static void monthlySalesReport(Counsumer<Map<YearMonth, Long>> consumer) {
    try (Stream<String> lines = Files.lines(Paths.get("./data.txt")) {
       		Map<YearMonth, Long> map = lines.skip(1)
                			.map(line -> line.split(","))
                			.collect(groupingBy(array -> YearMonth.from(formatter.parse(array[TIME], TreeMap::new, counting())));
                  
          return collect;                           
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

框架 跳过 博主 还没学呢 😂(预计11月份开Spring全家桶)

  • 什么是框架?
    • 半成品软件,帮助开发者快速构建应用程序
    • 框架提供的都是固定不变的、已知的、可以重用的代码
    • 而那些每个应用不同的业务逻辑,变化的、未知的部分,则在框架外由开发者自己实现
将未知交给子类
  • Spring 延迟创建 bean

image-20241008223538442

  1. public class C01JdbcTemlate {
        public static void main(String[] args) {
            HikariDataSoure dataSouce = new HikariDataSource();
            // 链接 mysql 服务器
            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test")
            dataSource.setUsername("root")
            dataSource.setPassword("root");
            
         //   try (Connection conn = dataSource.getConnection()) {
        //        PreparedStatement stat = conn.prepareStatement("select * from student");
         //       ResultSet rs = stat.executeQuery();
           //     while (rs.next()) {
          //          int id = rs.getInt("id");
        //            String name = rs.getString("name");
        //            String sex = rs.getString("sex");
             //       list.add(new Student(id, name, sex));
             //   }
          //  } catch (SQLException e) {
          //      throw new RuntimeException(e);
          //  }
            
            JdbcTemplate template = new JdbcTemplate(dataSource);
            List<Student> list = template.query("select * from student", (rs, row) -> {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String sex = rs.getString("sex");
                return new Student(id, name, sex);
            });
            
            for (Student student : list) {
                System.out.println(student);
            }
        }
        
        record Student(int id, String name, String sex) {
            
        }
    }
    
  • Spring
  • SpringBoot
序列化
public class TestSerializable { 
    public static void main(String[] args) throws Excepton {
        // 可序列化的函数对象
        Type1 lambda = (Type1 & Serializable) Student::getName;
        
        // 函数对象 <==> 字节码 会额外存储类和方法的信息,运行时就可以根据这些信息找到属性,从而进一步确定(列名)
        /*
        	for (Method method : lambda.getClass().getDeclaredMethods()) {
        		System.out.println(method);
        	}
        */
        
        SerializaedLambda invoke = (SerializedLambda) lambda.getClass().getDeclaredMethod("writeReplace").invoke(lambda);
        
        System.out.println(invoke.getClass()); // 哪个类使用了这个函数对象
        System.out.println(invoke.getImpClass()); // 哪个类实现了函数对象的逻辑
        System.out.println(invoke.getImplMethodName()); // 哪个方法实现了函数对象的逻辑
    }
    
    interface Type1 {
        String abc(Student student);
    }
}

并行

统计 Web 页面的访问次数
import static java.util.stream.Collectors.*;

public class ParalletTest {
    static Pattern reg = Pattern.compile("(\\S+) - \\[(.+)] (.+) (.+)");
    
    private static final int FILES = 100;
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Map<String, Long> map = one(0);
        for (Map.Entry<String, Long> e : map.entrySet()) {
            System.out.println(e);
        }
        
    }
    
    private static Map<String, Long> one(int i) {
        try(Stream<String> lines = Files.lines(Path.of(String.format("web_server_access_%d.log", i)))) {
        	    return lines.map(line->reg.matcher(line)) // reg::matcher
                  //  	.limit(10)
                    	.filter(mather -> mather.find()) // Matcher::find
                    	.map(matcher -> new String[]{matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4)})
                    	.collect(groupingBy(array -> array[2], counting()));
        } catch {
			throw new RuntimeException(e);
        }
        
        
    }
    
    private static void sequence() {
        long start == System.currentTimeMillis();
        Map<String, Long> m0 = new HashMap<>();
        for (int i = 0; i < FILES; i++) {
            Map<String, Long> mi = one(i);
            m0 = merge(m0, mi);
        }
        
        for (Map.Entry<String, Long> e : m0.entrySet()) {
            System.out.println(e);
        }
        
        System.our.println("cost: " + (System.currentTimeMillis() - start));
    }
    
    static Map<String, Long> merge(Map<String, Long> m1, Map<String, Long> m2) {
        
        return Stream.of(m1, m2)
            	.flatMap(m -> m.entrySet().stream())
            	.collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1 + v2)); 
    }
    
    private static void parallel() throws InterruptedException, ExecutionException {
        long start = System.currentTimeMillsi();
        for (int i = 0; i < FiLES; i++) {
            int k = i;
            CompletableFuture.supplyAsync(() -> one(k));
        }
        
        Completablefuture<Map<String, Long>> f0 = futures.getFirst();
        for (int i = 1; i < futures.size(); i++) {
            CompletableFuture<Map<String, Long>> fi = futures.get(i);
            f0.thenCombine(fi, (m0, mi) -> merge(m0, mi));
        }
        
        Map<String, Long> map = f0.get();
        for (Map.Entry<String, Long> e : map.entrySet()) {
            System.out.println(e);
        }
        
        System.out.println("cost: " + (System.currentTimeMillis() - start));
    }
}

UI 事件

import javax.swing.*;

// 在 UI 设计时的应用
public class UITest {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        
        JButton button = new JButton("点我");
        
        button.addActionListener(e -> System.out.println("已点击"));
        frame.add(button);
        
        
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

五.实现原理 Lambda、方法引用、闭包、可切分迭代器

原理 Lambda

import java.util.function.BinaryOperator;

public class C01Lambda1 {
    
    public static void main(String[] args) throws Throwable {
        
        BinaryOperator<Integer> lambda = (a, b) -> a + b;
        
        /*
        	lambda 表达式是一种语法糖, 它仍然会被翻译成 类,对象,方法
        1. 方法从哪来:编译器发现代码中出现了 lambda, 就会在当前类中生成 private static 方法,方法内包含的就是 lambda 的逻辑实验代码
            for (Method method : C01Lambda1.class.getDeclaredMethods()) {
                System.out.println(method);
            }
          
        2. 类和对象从哪来: 运行期间动态生成
        		MethodHandle
       		MethodHandle 的执行权限与上下文相关
            	原本有权限调用的方法,正常能运行,通过 MethodHandle 反射也能调用
            	原本没权限调用的方法,正常不能调用, MethodHandle 反射也调用不了
        3. 
       
        1. 反射调用静态方法
        MethodHandle mh = MethodHandles.lookup().findStatic(C01Lambda1.class, "lambda$main$2"),
        	MethodType.methodType(Integer.class, Integer.class, Integer.class);
        
        System.out.println(mh.invoke(1, 2));
        // 反射调用非静态方法
        MethodHandle mh2 = MethodHandles.lookup().findVirtual(MyLambda.class, "apply", MethodType.methodType(Integer.class, Integer.class, Integer.class));
        
        // 反射调用构造器方法
        MethodHandle mh3 = MethodHandles.lookup().findConstructor(MyLambda.class, MethodType.methodType(void.class));
        System.out.println(mh3.invoke()); //new MyLambda()
        
        System.out.println(new MyLambda());
        
        */
        
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        MethodHandle imp1 = lookup.findStatic(CO1Lambda1.class, "lambda$main$2",
                   MethodType.methodType(Integer.class, Integer.class, Integer.class));
        
        // 内部: 生成函数对象所需的类
        LambdaMetafactory.metafactory (
        	, // 1. lookup
            , // 2. 接口方法名
            , // 3. 创建函数对象工厂方法长相   BinaryOperator factory()
            , // 4. 接口方法长相
            , // 5. 实现方法(本例就是下面的静态方法 lambda$main$2)
            , // 6. 函数对象实际长相
            
            lookup,
            "apply",
            MethodType.methodType(BinaryOperator.class),
            MetodType.methodType(Object.class, Object.class, Object.class)
            impl,
            MethodType.methodType(Integer.class, Integer.class, Integer.class)
        );
        
        // BinaryOperator factory() { return new MyLambda() }
        MethodHandle mh = cs.getTarget(); // 就是函数对象工厂方法
		BinaryOperator<Integer> invoke = (BinaryOperator<Integer>) mh.invoke();
        System.out.println(invoke.apply(5, 6));
        
    }
        
        static final class MyLambda implements BinaryOperator<Integer> {
            private MyLambda() { }
            @Override
            public Integer apply(Integer e, Integer b) {
                returen lambda$main$0(a, b);
            }
        }
        
        
        private static Integer lambda$main$2(Integer a, Integer b) {
            return a + b;
        }
}

image-20241009091026289

image-20241009091117261

函数入口
import java.util.function.BinaryOperator;

public class C01Lambda1 {
    
    public static void main(String[] args) throws Throwable {
        
        BinaryOperator<Integer> lambda = (a, b) -> a + b;
       
    }
        
        static final class MyLambda implements BinaryOperator<Integer> {
            private MyLambda() { }
            @Override
            public Integer apply(Integer e, Integer b) {
                returen lambda$main$0(a, b);
            }
        }
        
        
        private static Integer lambda$main$2(Integer a, Integer b) {
            return a + b;
        }
}

重定向

image-20241009094105166

方法引用

public class C02MethodReference {
    public static void main(String[] args) {
        // 方法引用是一种语法糖,它仍然会被翻译成 类,对象,方法
        // 1.方法从哪来
        // 2.类,对象从哪来
        
        Function<Student, String> func = Student::getName(); // stu-> stu.getName()
        
        MethodHandles.Lookup lookup = MethodHandles.lookup();
        
        // 反射调用非静态方法
        MethodHandle impl = lookup.findVirtual(Student.class, "getName", MethodType.methodType(String.class));
        
        CallSite cs = LambdaMetafactory.metafactory (
        		lookup,
            	"apply",
            	MethodType.methodType(Function.class),
            	MethodType.methodType(Object.class, Object.class), // 实现接口:两个泛型参数
            	impl,	
            	MethodType.methodType(String.class, Student.class) // 返回类型 + 参数类型
        );
        
        Function<Student, String> invoke = (Function<Student, String>) cs.getTarget().invoke();
        Student stu = new Student();
        stu.name = "张三";
        System.out.println(invoke.apply(stu));
        
    }
    
    static final class MyMethodReference implements Function<Student, String> {
        
        @Override
        public String apply(Student student) {
            return student.getName();
        }
    }
    
    
    static class Student {
        
        private String name;
        
        public String getName() {
            return name;
        }
    }
}

image-20241009100513631

闭包

import java.util.function.BinaryOperator;

// -Djdk.invoke.LambdaMetafactory.dumpProxyClassFiles
public class C03Closure {
    public static void main(String[] args) {
        int c = 10;
        BinaryOperator<Integer> lambda = (a, b) -> a + b + c; // invoke dynamic
        test(lambda);
        
        for (Method method : C03Closure.class.getDeclaremethods()) {
            System.out.println(method);
        }
        
        // 1.方法
        // 2.类和对象
        static void test(BinaryOperator<Integer> lambda) {
            
        }
        
        
        final static class C03Closure$$Lambda implements BinaryOperator {
            private final int c;
            
            private C03Closure$$Lambda(int c) { this.c = c;}
            
            public Object apply(Object a, Object b) {
                return C03Clsure.lambda$main$1(this.c, (Integer)a, (Integer)b);
            }
        }
        // 反编译
        static private Integer lambda$main$1(int c, Integer a, Integer b) {
            reutrn a + b + c;
        }
    }
}
静态变量
public class C04Closure {
    static int c = 10;
    public static void main(String[] args) {
        BinaryOperator<Integer> lambda = (a, b) - a + b + c;
        /*
        	System.out.println(lambda.apply(1, 2));
        	c = 20;
        	System.out.println(lambda.apply(1, 2));
        */
        
        for (Method method : C04Closure.class.getDeclaredMethods()) {
            System.out.println(method);
        }
        
        static final class C04Closure$$Lambda implements BinaryOperator {
            private c04Closure$$Lambda() {
                
            }
            
            public Object apply(Object a, Object b) {
                return C04Closure.lambda$main$1((Integer)a, (Integer)b );
            }
        }
    }
    
    private static Integer lambda$1(Integer a, Integer b) {
        return a + b + C04Closure.c;
    }
}

可切分迭代器

image-20241009103201318

public class C06Spliterator {
    public static void main(String[] args) {
        List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        
        // Stream<Integer> s1 = list.stream();
        // Stream<Integer> s2 = Arrays.stream(array);
        
        Spliterator<Integer> sp1 = list.spliterator();
        
        Spliterator<Integer> sp2 = sp1.trySplit();
        Spliterator<Integer> sp3 = sp2.trySplit();
        
        System.out.println("sp1:");
        sp1.tryAdvance(System.out::println);
        System.out.println("sp2:");
        sp2.tryAdvance(System.out::println);
        System.out.println("sp3:")
        sp3.tryAdvance(System.out::println);
        System.out.println("==========================");
        
        
        CompletableFuture.supplyAsync(() -> StreamSupport.stream(sp2, false).reduce(0, Integer::sum))
            	.thenAccept(x -> logger.info("{}", x));
        
        CompletableFuture.supplyAsync(() -> StreamSupport.stream(sp3, false).reduce(0, Integer::sum))
            	.thenAccept(x -> logger.info("{}", x));
        
        System.in.read();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2203747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

喜大普奔!eBay英国站取消个人卖家几乎所有销售费用!

二手电商市场竞争愈发激烈&#xff0c;eBay开始放大招了&#xff01;为什么说是取消个人卖家的几乎所有销售费用呢&#xff1f;一起来了解一下—— eBay英国站个人卖家无需支付最终交易费或监管运营费&#xff0c;这大大减轻了个人卖家的交易成本。不过需要注意的是&#xff0…

后端开发——规则引擎简介(Drools)

目录 什么是规则引擎&#xff1f;规则引擎带来的好处;Drools案例规则引擎的工作原理及应用场景常见的规则引擎及对比工作流引擎与规则引擎有什么不同 什么是规则引擎&#xff1f; 规则引擎&#xff0c;听起来高大上&#xff0c;其实可以理解为一种帮助你做“决策”的工具。你可…

使用浏览器原生API实现录屏功能

好早之前写了个小deme,本来都忘了,现在无意中又翻出来了,所以也来记录一下吧! 废话不说了,直接上代码了: <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content=&q…

byte[]/InputStream/MultipartFile之间进行转换

前言 问题产生&#xff1a; 最近开发项目的时候&#xff0c;遇到了文件上传对象转换的问题 -> 我在对接抖音开放平台的时候&#xff0c;有一个图片上传的接口&#xff0c;需要将byte[]转为MultipartFile 对象&#xff0c;但是发现根本没有这样的工具类&#xff0c;后面翻阅…

无人机之巡航控制篇

一、巡航控制的基本原理 无人机巡航控制的基本原理是通过传感器检测无人机的飞行状态和环境信息&#xff0c;并将其反馈给控制器。控制器根据反馈信息和任务需求&#xff0c;计算出无人机的控制指令&#xff0c;并将其发送给执行机构。执行机构根据控制器的控制指令&#xff0c…

数据结构与算法——Java实现 33.堆排序

刻意去找的东西&#xff0c;往往是找不到的。 天下万物的来和去&#xff0c;都有它的时间。 —— 24.10.10 使用堆进行排序 算法描述 1.heapify 建立大顶堆&#xff08;所有结点的父元素大于子元素&#xff09; 2.将堆顶与堆底交换(最大元素被交换到堆底)&#xff0c;缩小并…

Python测试框架--Allure

严格意义上讲 Allure 不算是测试框架&#xff0c;但是它是生成漂亮测试报告的开源工具&#xff0c;搭配 Pytest 测试框架食用更搭。 也就是说 Allure 是在 Pytest 执行完生成的测试数据的基础上&#xff0c;对测试数据进行处理统计&#xff0c;生成格式统一、美观的测试报告。 …

java反射Class类的api

目录 Class类 1.构造器相关 1&#xff09;Constructor getConstructor(Class... parameterTypes): 2&#xff09;Constructor[] getConstructors(): 3&#xff09;Constructor getDeclaredConstructor(Class... parameterTypes): 4&#xff09;Constructor[] getDeclaredConstr…

国外火出圈儿的PM御用AI编程工具Bolt.new效果干不过国产的CodeFlying?号称全新定义全栈开发流程?

不知道大家最近有没有发现国外的很多AI都在挤破脑袋想去提升大模型的编程能力&#xff0c; 离我们最近的是上周Openai 发布的全新模型GPT-4o-Canvas&#xff0c; 拥有超强的代码编写能力。 另外还有LlamaCoder、Cursor、Claude artifacts、Replit... 光是今年一年就推出了好…

深入理解Transformer的笔记记录(精简版本)---- Transformer

自注意力机制开启大规模预训练时代 1 从机器翻译模型举例 1.1把编码器和解码器联合起来看待的话,则整个流程就是(如下图从左至右所示): 1.首先,从编码器输入的句子会先经过一个自注意力层(即self-attention),它会帮助编码器在对每个单词编码时关注输入句子中的的其他单…

xtu oj 四位数

样例输入# 2 1990 1111样例输出# 5 0 分离整数与合并 AC代码 #include<stdio.h> //判断四个数码是否相等 int Judge(int n){int flag1;int gn%10,sn/10%10,bn/100%10,qn/1000;if(gs&&gb&&gq)flag0;return flag; } int main(){int T;scanf("%d…

AI无人直播风口,云微客替你抓住了

现在很多老板都在找风口&#xff0c;其实风口就是我们大家看得见、摸得着的东西&#xff0c;就比如说近期比较火热的直播带货就属于是一个风口。可能很多老板会说直播、短视频之类的风口过于高科技&#xff0c;搞不来也搞不懂&#xff0c;跟自己好像没太大关系。 其实不然&…

嵌入式开发:STM32 硬件 CRC 使用

测试平台&#xff1a;STM32G474系列 STM32硬件的CRC不占用MCU的资源&#xff0c;计算速度快。由于硬件CRC需要配置一些选项&#xff0c;配置不对就会导致计算结果错误&#xff0c;导致使用上没有软件计算CRC方便。但硬件CRC更快的速度在一些有时间资源要求的场合还是非…

【二叉搜索树】1 leetcode 98 验证二叉搜索树

1 题目描述 题目链接&#xff1a;验证二叉搜索树 2 题目解析 搜索二叉树的特点就是&#xff0c; 中序遍历之后的值是有序的。 根据这个性质&#xff0c;可以对树进行中序遍历&#xff0c;将遍历的结果存入到vector中最后判断vector中的值的顺序。如果是从小到大有序的&…

变色龙算法(CSA)的MATLAB代码复现

目录 1 变色龙算法优化BP神经网络代码复现 2 变色龙算法优化支持向量机代码复现 3 变色龙算法优化长短期记忆神经网络代码复现 1 变色龙算法优化BP神经网络代码复现 1&#xff09;单输出回归预测&#xff1a;单输出回归预测&#xff1a;变色龙算法优化BP神经网络模型&#…

MinIO分片上传超大文件(纯服务端)

目录 一、MinIO快速搭建1.1、拉取docker镜像1.2、启动docker容器 二、分片上传大文件到MinIO2.1、添加依赖2.2、实现MinioClient2.3、实现分片上传2.3.0、初始化MinioClient2.3.1、准备分片上传2.3.2、分片并上传2.3.2.1、设置分片大小2.3.2.2、分片 2.3.3、分片合并 三、测试3…

Windows命令行执行cmake

生成Win32 工程并编译 cmake ../../ -G "Visual Studio 16 2019" -A Win32set pathC:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin;%path%msbuild VideoNetOptimization.sln /p:ConfigurationRelWithDebInfo /p:PlatformWin3…

MSYS2+GCC 安装与应用保姆手册

msys2 提供可在Windows下使用 GCC 编译器&#xff1b;并且&#xff0c;借助 Linux 包管理功能&#xff0c;可轻松下载丰富的可在Windows下直接使用的 C/C 开发包&#xff0c;包括编译好的二进制包。 网络库asio、准标准库boost、zip解压缩、json格式处理、引擎 SDL……十八般兵…

2025年软考高项(信息系统项目管理师)包过班靠谱吗?

随着新一轮软考的到来&#xff0c;出现了很多“软考包过”的信息&#xff0c;但需要注意的是&#xff0c;“软考包过”根本不可信&#xff01; 因此不要想着依靠不正当手段来取得证书&#xff0c;要知道&#xff0c;如今 软考 由笔试变为机考&#xff0c;很难作弊&#xff0c;…

​速卖通、敦煌卖家备战双11+黑五前,怎么增加店铺曝光?

在速卖通这个竞争激烈的跨境电商平台上&#xff0c;店铺曝光率是决定销售成败的关键因素之一。为了在众多商家中脱颖而出&#xff0c;增加速卖通店铺曝光显得尤为重要。速卖通怎么增加店铺曝光&#xff1f; 一、速卖通怎么增加店铺曝光? 1、优化产品列表 速卖通的产品列表是…