Java函数知识点大全(四)

简介: 教程来源 https://dnuhf.cn/ 本文系统讲解Java函数式编程核心:Lambda表达式(含语法、方法引用四种形式)、常用函数式接口(Predicate/Function/Consumer等)、Stream API(中间/终端操作、分组聚合)、异常处理技巧及方法设计最佳实践,涵盖从基础到高级的完整知识体系。

十、Lambda表达式

10.1 Lambda基础

public class LambdaDemo {

    // 函数式接口
    @FunctionalInterface
    interface StringOperation {
        String operate(String s);
    }

    @FunctionalInterface
    interface MathOperation {
        int operate(int a, int b);
    }

    public void demo() {
        // 传统匿名内部类
        MathOperation addOld = new MathOperation() {
            @Override
            public int operate(int a, int b) {
                return a + b;
            }
        };

        // Lambda表达式
        MathOperation add = (a, b) -> a + b;
        MathOperation subtract = (a, b) -> a - b;
        MathOperation multiply = (a, b) -> a * b;

        // 带代码块的Lambda
        MathOperation divide = (a, b) -> {
            if (b == 0) {
                throw new ArithmeticException("除数不能为0");
            }
            return a / b;
        };

        // 单参数Lambda(可省略括号)
        StringOperation toUpper = s -> s.toUpperCase();
        StringOperation toLower = String::toLowerCase;  // 方法引用

        // 使用Lambda
        System.out.println(calculate(10, 5, add));        // 15
        System.out.println(calculate(10, 5, subtract));   // 5
        System.out.println(calculate(10, 5, multiply));   // 50
    }

    private int calculate(int a, int b, MathOperation op) {
        return op.operate(a, b);
    }
}

10.2 方法引用

public class MethodReferenceDemo {

    // 方法引用的四种形式

    // 1. 静态方法引用:Class::staticMethod
    public void staticRef() {
        // Lambda形式
        Function<String, Integer> lambda = s -> Integer.parseInt(s);
        // 方法引用形式
        Function<String, Integer> ref = Integer::parseInt;

        // 使用
        Integer num = ref.apply("123");
    }

    // 2. 实例方法引用:instance::method
    public void instanceRef() {
        List<String> list = Arrays.asList("a", "b", "c");

        // Lambda形式
        list.forEach(s -> System.out.println(s));
        // 方法引用形式
        list.forEach(System.out::println);
    }

    // 3. 特定类型实例方法引用:Class::method
    public void specificTypeRef() {
        List<String> list = Arrays.asList("hello", "world");

        // Lambda形式
        list.sort((s1, s2) -> s1.compareToIgnoreCase(s2));
        // 方法引用形式
        list.sort(String::compareToIgnoreCase);
    }

    // 4. 构造方法引用:Class::new
    public void constructorRef() {
        // Lambda形式
        Supplier<List<String>> lambda = () -> new ArrayList<>();
        // 方法引用形式
        Supplier<List<String>> ref = ArrayList::new;

        // 带参数的构造器
        Function<String, Integer> func = Integer::new;  // new Integer(String)

        List<String> list = ref.get();
    }
}

十一、函数式编程

11.1 常用函数式接口

import java.util.function.*;

public class FunctionalInterfacesDemo {

    // 1. Predicate<T>:断言(返回boolean)
    public void predicateDemo() {
        Predicate<Integer> isEven = n -> n % 2 == 0;
        Predicate<String> isNotEmpty = s -> s != null && !s.isEmpty();
        Predicate<Integer> isPositive = n -> n > 0;

        System.out.println(isEven.test(4));   // true
        System.out.println(isPositive.test(-1)); // false

        // 组合Predicate
        Predicate<Integer> isEvenAndPositive = isEven.and(isPositive);
        Predicate<Integer> isEvenOrPositive = isEven.or(isPositive);
        Predicate<Integer> isNotEven = isEven.negate();
    }

    // 2. Function<T,R>:转换(输入T,输出R)
    public void functionDemo() {
        Function<String, Integer> length = String::length;
        Function<Integer, String> toString = Object::toString;
        Function<String, String> toUpper = String::toUpperCase;

        // 组合Function
        Function<String, String> upperThenLength = 
            toUpper.andThen(length).andThen(toString);

        // 使用
        Integer len = length.apply("Hello");  // 5
        String result = upperThenLength.apply("Hello");  // "5"
    }

    // 3. Consumer<T>:消费(无返回值)
    public void consumerDemo() {
        Consumer<String> printer = System.out::println;
        Consumer<List<String>> listPrinter = list -> list.forEach(System.out::println);

        // 组合Consumer
        Consumer<String> logAndPrint = 
            s -> System.out.println("Log: " + s).andThen(printer);

        printer.accept("Hello");
    }

    // 4. Supplier<T>:供应(无输入,返回T)
    public void supplierDemo() {
        Supplier<Double> random = Math::random;
        Supplier<LocalDateTime> now = LocalDateTime::now;
        Supplier<List<String>> emptyList = ArrayList::new;

        Double value = random.get();
        LocalDateTime current = now.get();
    }

    // 5. UnaryOperator<T>:一元操作(Function的特例)
    public void unaryOperatorDemo() {
        UnaryOperator<String> toUpper = String::toUpperCase;
        UnaryOperator<Integer> square = n -> n * n;

        String result = toUpper.apply("hello");  // "HELLO"
        Integer squared = square.apply(5);        // 25
    }

    // 6. BinaryOperator<T>:二元操作(BiFunction的特例)
    public void binaryOperatorDemo() {
        BinaryOperator<Integer> add = Integer::sum;
        BinaryOperator<Integer> max = Integer::max;

        Integer sum = add.apply(10, 20);   // 30
        Integer maximum = max.apply(10, 20); // 20
    }

    // 7. BiFunction<T,U,R>:双参数函数
    public void biFunctionDemo() {
        BiFunction<String, Integer, String> repeat = (s, n) -> s.repeat(n);
        BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;

        String repeated = repeat.apply("Hi", 3);  // "HiHiHi"
    }
}

11.2 Stream API

public class StreamDemo {

    public void streamOperations() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 中间操作
        List<Integer> result = numbers.stream()
            .filter(n -> n % 2 == 0)           // 过滤偶数
            .map(n -> n * 2)                    // 乘以2
            .distinct()                         // 去重
            .sorted(Comparator.reverseOrder())  // 降序排序
            .limit(3)                           // 限制3个
            .skip(1)                            // 跳过1个
            .peek(n -> System.out.println("处理: " + n))  // 调试
            .collect(Collectors.toList());      // 终端操作:收集

        // 常用终端操作
        // count()
        long count = numbers.stream().filter(n -> n > 5).count();

        // forEach()
        numbers.stream().forEach(System.out::println);

        // reduce()
        Optional<Integer> sum = numbers.stream().reduce(Integer::sum);
        Optional<Integer> max = numbers.stream().reduce(Integer::max);

        // anyMatch / allMatch / noneMatch
        boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0);
        boolean allPositive = numbers.stream().allMatch(n -> n > 0);

        // findFirst / findAny
        Optional<Integer> first = numbers.stream().findFirst();
        Optional<Integer> any = numbers.parallelStream().findAny();

        // toArray
        Integer[] array = numbers.stream().toArray(Integer[]::new);
    }

    // 分组和聚合
    public void groupingDemo() {
        List<Person> persons = Arrays.asList(
            new Person("张三", "北京", 25),
            new Person("李四", "上海", 30),
            new Person("王五", "北京", 28),
            new Person("赵六", "上海", 32)
        );

        // 按城市分组
        Map<String, List<Person>> byCity = persons.stream()
            .collect(Collectors.groupingBy(Person::getCity));

        // 按城市分组,统计人数
        Map<String, Long> countByCity = persons.stream()
            .collect(Collectors.groupingBy(Person::getCity, Collectors.counting()));

        // 按城市分组,计算平均年龄
        Map<String, Double> avgAgeByCity = persons.stream()
            .collect(Collectors.groupingBy(Person::getCity, 
                     Collectors.averagingInt(Person::getAge)));

        // 多级分组
        Map<String, Map<Integer, List<Person>>> multiGroup = persons.stream()
            .collect(Collectors.groupingBy(Person::getCity,
                     Collectors.groupingBy(Person::getAge)));
    }
}

十二、异常处理中的方法

public class ExceptionMethodDemo {

    // 1. 方法声明抛出异常
    public void readFile(String path) throws IOException {
        if (path == null) {
            throw new IllegalArgumentException("路径不能为null");
        }

        Files.readAllLines(Paths.get(path));
    }

    // 2. 方法内部捕获异常
    public void safeReadFile(String path) {
        try {
            Files.readAllLines(Paths.get(path));
        } catch (IOException e) {
            System.err.println("读取文件失败: " + e.getMessage());
            // 记录日志、返回默认值等
        }
    }

    // 3. 异常转译(包装异常)
    public void wrappedException(String path) throws ServiceException {
        try {
            Files.readAllLines(Paths.get(path));
        } catch (IOException e) {
            throw new ServiceException("文件服务错误", e);
        }
    }

    // 4. 自定义异常
    class ServiceException extends Exception {
        public ServiceException(String message) {
            super(message);
        }

        public ServiceException(String message, Throwable cause) {
            super(message, cause);
        }
    }

    // 5. try-with-resources自动关闭
    public void tryWithResources() {
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
            String line = reader.readLine();
            System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

十三、方法内联与性能

public class MethodPerformanceDemo {

    // 1. 小方法适合内联
    private int add(int a, int b) {
        return a + b;  // 简单操作,JVM会内联
    }

    // 2. 频繁调用的方法应简洁
    public void hotMethod() {
        for (int i = 0; i < 1000000; i++) {
            // 调用简洁的方法
            int result = add(i, i + 1);
        }
    }

    // 3. 避免不必要的getter/setter(JVM可优化)
    private String name;

    public String getName() {
        return name;  // JVM会内联此类简单访问
    }

    // 4. 性能测试
    public void performanceTest() {
        long start = System.nanoTime();

        // 执行测试

        long duration = System.nanoTime() - start;
        System.out.println("执行时间: " + duration + " ns");
    }
}

十四、最佳实践

14.1 方法设计原则

public class MethodBestPractices {

    // 1. 单一职责:一个方法只做一件事
    // 不好
    public void processUser(String name, int age, String email) {
        // 验证、保存、发送邮件混在一起
    }

    // 好
    public boolean validateUser(String name, int age, String email) { }
    public void saveUser(String name, int age, String email) { }
    public void sendWelcomeEmail(String email) { }

    // 2. 方法命名规范
    // 动词开头,驼峰命名
    public void calculateTotal() { }
    public boolean isValidEmail(String email) { }
    public User findUserById(Long id) { }

    // 3. 参数数量控制
    // 避免超过3-4个参数
    // 不好
    public void createUser(String name, int age, String email, String phone, 
                           String address, String city, String country) { }

    // 好:使用对象封装
    public void createUser(UserDto userDto) { }

    // 4. 返回类型规范
    // 返回空集合而非null
    public List<String> getNames() {
        return Collections.emptyList();  // 而不是返回null
    }

    // 返回Optional
    public Optional<User> findUser(Long id) {
        return Optional.ofNullable(userMap.get(id));
    }

    // 5. 方法可见性
    private void internalHelper() { }      // 内部使用
    protected void forSubclass() { }       // 供子类扩展
    public void apiMethod() { }            // 公开API
}

14.2 常见反模式

public class MethodAntiPatterns {

    // 反模式1:过长的方法
    public void tooLongMethod() {
        // 数百行代码
        // 应该拆分为多个小方法
    }

    // 反模式2:过多的参数
    public void tooManyParams(int p1, int p2, int p3, int p4, int p5, 
                              int p6, int p7, int p8, int p9, int p10) {
        // 使用对象封装参数
    }

    // 反模式3:过多的返回值
    public int[] badMethod() {
        // 返回多个值但含义不明确
        return new int[]{1, 2, 3};  // 各值含义不清
    }

    // 反模式4:副作用
    private List<String> list = new ArrayList<>();

    public void methodWithSideEffect(String item) {
        // 修改全局状态,应该避免或明确文档说明
        list.add(item);
    }

    // 反模式5:使用异常控制流程
    public void useExceptionForFlow() {
        try {
            // 正常流程
        } catch (Exception e) {
            // 控制流程
        }
    }
}

Java函数(方法)是Java程序的基本构建块。从基础的方法声明、参数传递、方法重载,到高级的Lambda表达式、函数式接口、Stream API,Java的函数体系已经发展成为一套完整而强大的编程范式。
来源:
https://dnuhf.cn/category/food.html

相关文章
|
10天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
11192 104
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
10天前
|
人工智能 IDE API
2026年国内 Codex 安装教程和使用教程:GPT-5.4 完整指南
Codex已进化为AI编程智能体,不仅能补全代码,更能理解项目、自动重构、执行任务。本文详解国内安装、GPT-5.4接入、cc-switch中转配置及实战开发流程,助你从零掌握“描述需求→AI实现”的新一代工程范式。(239字)
5827 136
|
8天前
|
人工智能 并行计算 Linux
本地私有化AI助手搭建指南:Ollama+Qwen3.5-27B+OpenClaw阿里云/本地部署流程
本文提供的全流程方案,从Ollama安装、Qwen3.5-27B部署,到OpenClaw全平台安装与模型对接,再到RTX 4090专属优化,覆盖了搭建过程的每一个关键环节,所有代码命令可直接复制执行。使用过程中,建议优先使用本地模型保障隐私,按需切换云端模型补充功能,同时注重显卡温度与显存占用监控,确保系统稳定运行。
2007 6
|
6天前
|
人工智能 自然语言处理 供应链
【最新】阿里云ClawHub Skill扫描:3万个AI Agent技能中的安全度量
阿里云扫描3万+AI Skill,发现AI检测引擎可识别80%+威胁,远高于传统引擎。
1409 3
|
7天前
|
人工智能 Linux API
离线AI部署终极手册:OpenClaw+Ollama本地模型匹配、全环境搭建与问题一站式解决
在本地私有化部署AI智能体,已成为隐私敏感、低成本、稳定运行的主流方案。OpenClaw作为轻量化可扩展Agent框架,搭配Ollama本地大模型运行工具,可实现完全离线、无API依赖、无流量费用的个人数字助理。但很多用户在实践中面临三大难题:**不知道自己硬件能跑什么模型、显存/内存频繁爆仓、Skills功能因模型不支持工具调用而失效**。
3389 7