ZetCode

Java ToLongFunction 接口

最后修改时间:2025 年 4 月 16 日

java.util.function.ToLongFunction 接口表示一个接受一个参数并产生一个 long 类型结果的函数。它是一个函数式接口,只有一个抽象方法 applyAsLong。 这种专门的函数在处理基本类型 long 时避免了装箱开销。

ToLongFunction 是 Java 8 中新增的 Java 函数式编程实用程序的一部分。它特别适用于处理基本 long 值的流操作。该接口有助于编写高效的数值代码。

ToLongFunction 接口概述

ToLongFunction 接口包含一个必须实现的抽象方法。与常规 Function 不同,它返回一个基本类型 long 而不是一个对象。这为数值运算提供了性能优势。

@FunctionalInterface
public interface ToLongFunction<T> {
    long applyAsLong(T value);
}

上面的代码展示了 ToLongFunction 的简单结构。它使用泛型作为输入类型 T,但始终返回基本类型 long。该接口使用 @FunctionalInterface 注解,以表明其单一抽象方法的性质。

ToLongFunction 的基本用法

使用 ToLongFunction 的最简单方法是使用 lambda 表达式。我们在 applyAsLong 方法中定义了如何将输入转换为 long。该示例将字符串转换为它们的长度(long 类型)。

Main.java
package com.zetcode;

import java.util.function.ToLongFunction;

public class Main {

    public static void main(String[] args) {

        // Define a function that takes String and returns its length as long
        ToLongFunction<String> lengthFunction = s -> s.length();
        
        // Apply the function
        System.out.println("Length of 'hello': " + lengthFunction.applyAsLong("hello"));
        System.out.println("Length of 'functional': " + lengthFunction.applyAsLong("functional"));
        
        // Function using method reference
        ToLongFunction<String> lengthMethodRef = String::length;
        System.out.println("Length via method ref: " + lengthMethodRef.applyAsLong("method"));
    }
}

此示例演示了使用 lambda 和方法引用的 ToLongFunction 的基本用法。 lengthFunction 接受 String 并返回基本类型 long。 我们将其应用于不同的字符串。 方法引用为现有方法提供了简洁的语法。

ToLongFunction 与自定义对象

ToLongFunction 可以通过从自定义对象中提取 long 值来使用它们。这在处理流中的对象集合时非常有用。该示例计算员工的工资,以 long 类型表示。

Main.java
package com.zetcode;

import java.util.function.ToLongFunction;

class Employee {
    private String name;
    private long salary;
    
    public Employee(String name, long salary) {
        this.name = name;
        this.salary = salary;
    }
    
    public long getSalary() { return salary; }
}

public class Main {

    public static void main(String[] args) {

        // Function to extract salary from Employee
        ToLongFunction<Employee> salaryExtractor = Employee::getSalary;
        
        Employee emp1 = new Employee("John", 75000L);
        Employee emp2 = new Employee("Sarah", 85000L);
        
        System.out.println("John's salary: " + salaryExtractor.applyAsLong(emp1));
        System.out.println("Sarah's salary: " + salaryExtractor.applyAsLong(emp2));
    }
}

此示例展示了 ToLongFunction 与自定义 Employee 对象的配合使用。 salaryExtractor 函数使用方法引用来获取工资值。 这种模式在处理数值运算中的对象集合时很常见。

ToLongFunction 在流操作中

ToLongFunction 常用 于 Java Stream 的数值处理。 mapToLong 操作接受一个 ToLongFunction,将流元素转换为基本类型 long。这使得高效的数值管道成为可能。

Main.java
package com.zetcode;

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

public class Main {

    public static void main(String[] args) {

        List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
        
        // Calculate total characters using mapToLong
        long totalChars = words.stream()
            .mapToLong(String::length)
            .sum();
            
        System.out.println("Total characters: " + totalChars);
        
        // Calculate average word length
        double avgLength = words.stream()
            .mapToLong(String::length)
            .average()
            .orElse(0.0);
            
        System.out.println("Average length: " + avgLength);
    }
}

此示例演示了 ToLongFunction 在 Stream 操作中的应用。 我们使用方法引用 String::length 作为 ToLongFunction。 mapToLong 操作创建一个 LongStream,用于高效的数值处理,如求和和求平均值。

ToLongFunction 与基本类型数组

ToLongFunction 可以高效地处理基本类型数组。这在处理大型数值数据集时很有用。该示例使用 ToLongFunction 计算数组统计信息。

Main.java
package com.zetcode;

import java.util.Arrays;
import java.util.function.ToLongFunction;

public class Main {

    public static void main(String[] args) {

        int[] numbers = {10, 20, 30, 40, 50};
        
        // Function to convert int to long (needed for large numbers)
        ToLongFunction<Integer> intToLong = x -> (long) x;
        
        // Process array using ToLongFunction
        long sum = Arrays.stream(numbers)
            .mapToLong(intToLong)
            .sum();
            
        System.out.println("Sum of array: " + sum);
        
        // Another example: square each number
        long[] squares = Arrays.stream(numbers)
            .mapToLong(x -> (long) x * x)
            .toArray();
            
        System.out.println("Squares: " + Arrays.toString(squares));
    }
}

此示例展示了 ToLongFunction 处理基本类型数组。 我们将 int 值转换为 long,以防止计算溢出。 mapToLong 操作可对数组元素进行高效的数值转换。

将 ToLongFunction 与其他函数式接口结合使用

ToLongFunction 可以与其他函数式接口结合使用,以进行更复杂的操作。 该示例展示了在流管道中应用 ToLongFunction 之前进行过滤。

Main.java
package com.zetcode;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.function.ToLongFunction;

public class Main {

    public static void main(String[] args) {

        List<String> products = Arrays.asList("Laptop:1200", "Mouse:25", 
            "Keyboard:45", "Monitor:300");
            
        // Predicate to filter expensive products
        Predicate<String> expensive = s -> {
            long price = Long.parseLong(s.split(":")[1]);
            return price > 100;
        };
        
        // ToLongFunction to extract price
        ToLongFunction<String> priceExtractor = s -> 
            Long.parseLong(s.split(":")[1]);
        
        // Calculate total of expensive products
        long total = products.stream()
            .filter(expensive)
            .mapToLong(priceExtractor)
            .sum();
            
        System.out.println("Total expensive products: $" + total);
    }
}

此示例在流管道中将 Predicate 与 ToLongFunction 结合使用。 我们首先过滤掉昂贵的产品,然后提取价格作为 long 类型进行求和。 这展示了函数式接口如何协同工作以进行数据处理。

ToLongFunction 与 Function 的比较

虽然 ToLongFunctionFunction 相似,但它们之间存在关键差异。 ToLongFunction 返回基本类型 long,以便更好地进行数值运算。 Function 返回一个对象,需要装箱。

Main.java
package com.zetcode;

import java.util.function.Function;
import java.util.function.ToLongFunction;

public class Main {

    public static void main(String[] args) {

        // ToLongFunction - returns primitive long
        ToLongFunction<String> toLongFunc = s -> Long.parseLong(s);
        long primitiveLong = toLongFunc.applyAsLong("123456789012");
        
        // Function - returns Long object
        Function<String, Long> func = s -> Long.parseLong(s);
        Long objectLong = func.apply("123456789012");
        
        System.out.println("ToLongFunction result: " + primitiveLong);
        System.out.println("Function result: " + objectLong);
        
        // Performance comparison
        long start = System.nanoTime();
        for (int i = 0; i < 1_000_000; i++) {
            toLongFunc.applyAsLong("123");
        }
        long toLongTime = System.nanoTime() - start;
        
        start = System.nanoTime();
        for (int i = 0; i < 1_000_000; i++) {
            func.apply("123");
        }
        long funcTime = System.nanoTime() - start;
        
        System.out.println("ToLongFunction time: " + toLongTime);
        System.out.println("Function time: " + funcTime);
    }
}

此示例比较了 ToLongFunction 和 Function。 它们都将字符串解析为 long 类型,但 ToLongFunction 避免了装箱开销。 性能测试表明,由于基本类型处理,ToLongFunction 在数值运算方面更快。

ToLongFunction 的特殊变体

Java 为不同的输入类型提供了 ToLongFunction 的特殊变体。 这些包括 IntToLongFunctionDoubleToLongFunction 等基本类型输入。

Main.java
package com.zetcode;

import java.util.function.DoubleToLongFunction;
import java.util.function.IntToLongFunction;
import java.util.function.LongUnaryOperator;

public class Main {

    public static void main(String[] args) {

        // IntToLongFunction example
        IntToLongFunction square = x -> (long) x * x;
        System.out.println("Square of 5: " + square.applyAsLong(5));
        
        // DoubleToLongFunction example (rounding)
        DoubleToLongFunction rounder = d -> Math.round(d);
        System.out.println("Rounded 3.7: " + rounder.applyAsLong(3.7));
        
        // LongUnaryOperator (special case of ToLongFunction)
        LongUnaryOperator increment = x -> x + 1;
        System.out.println("Incremented 10: " + increment.applyAsLong(10));
    }
}

此示例演示了特殊的 ToLongFunction 变体。 这些接口直接接受基本类型输入,避免了装箱开销。 它们适用于 Java 应用程序中的高性能数值处理。

来源

Java ToLongFunction 接口文档

在本文中,我们介绍了 Java ToLongFunction 接口的基本方法和特性。 理解这些概念对于在 Java 应用程序中进行高效的数值处理和函数式编程至关重要。

作者

我的名字是 Jan Bodnar,我是一位经验丰富的程序员,在编程领域拥有多年经验。 我从 2007 年开始撰写编程文章,至今已撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过八年的教学经验,致力于分享我的知识,并帮助其他人掌握编程概念。

列出所有Java教程