我试图理解下一个示例中的一些内容:
Stream.of("a1", "a2", "a3")
.map(s -> s.substring(1))
.mapToInt(Integer::parseInt)
.max()
. (etc.)
为什么mapToInt需要
Integer::parseInt
作为参数?难道不应该是隐含的吗?这个参数是不是多余了?
Stream#mapToInt(ToIntFunction)
的作用和 ToIntFunction
参数的作用非常重要。
mapToInt
的调用是流将要做的什么(即将元素映射到 int
)。ToIntFunction
参数是如何流将每个元素映射到int
。他们是否可以包含一个无参数
mapToInt
方法,隐式地将 String
解析为 int
?是的,但是 看看它对于 Stream#sorted()
的效果有多好,而且这种情况远不像无参数 mapToInt
方法那样任意或模糊。
无参数
sorted
方法假设元素是 Comparable
,这是 Java 中一个基本的、标准化的、广泛使用的接口——任何类都可以实现该接口(而只有一个类可以是 String
) 。因此,虽然该方法不是类型安全的,但可以认为用例足够常见以证明其存在的合理性。
但是,假设元素是
mapToInt
并将其内容解析为 String
的无参数 int
方法是一个非常具体的用例。为什么这样一个通用的 API 会提供这样一个特定的操作?这将是一个完全武断的决定,没有合理的理由。例如,为什么不将每个 String
映射到其 length
呢?为什么 String
被特殊处理而不是其他类型?因此,该方法接受一个 ToIntFunction
参数,该参数描述了 如何 根据具体情况将元素映射到 int
。
注意到
Integer::parseInt
是一个方法引用可能会有所帮助,它是一个简单的lambda表达式的简写。两者都是功能接口的实现,这比使用匿名类更简洁。换句话说,您正在创建一个新的 ToIntFunction
实例并将其作为参数传递。
以下所有内容在功能上都是等效的:
// method reference
stream.mapToInt(Integer::parseInt)
// lambda expression
stream.mapToInt((String value) -> Integer.parseInt(value)) // explicit parameter types
stream.mapToInt(value -> Integer.parseInt(value)) // implicit parameter types
// anonymous class
stream.mapToInt(new ToIntFunction<>() {
@Override
public int applyAsInt(String value) {
return Integer.parseInt(value);
}
})
其中
stream
是 Stream<String>
。
您正在执行的操作如下:
Stream.of("a1", "a2", "a3") //step1
.map(s -> s.substring(1)) //step2
.mapToInt(Integer::parseInt) //step3
.max()
您定义一个字符串流(在步骤 1 中),然后将其中的每个字符串丢弃并丢弃其中的 1 个字符,留下“1”、“2”和“3”的流,(步骤 2)但请注意,这些仍然是字符串对象... 然后将其转换为整数,因此您需要为“mapToInt”提供一个“函数”,该函数接受字符串作为参数并返回整数(步骤3)
这是在 Integer 类中定义的:
https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#parseInt(java.lang.String)
你当然可以编写并传递你自己的函数......但为什么要重新发明轮子呢? :)
substring
返回字符串而不是整数。
mapToInt
将对象流(在本例中为字符串)转换为 IntStream
int 基元。但是它不知道如何进行映射,您需要为其提供一个函数,在您的情况下是parseInt
。
实际上,读完这里的友善答案后我明白了 1.我的问题不够清楚。 2.答案...
那么,
我真正的意思是 - 将 Integer::parseInt 作为参数传递给 mapToInt 不是多余的吗?因为我觉得mapToInt准确地描述了该方法的目的 - 将对象映射到int,并且添加parseInt是不必要的,因为它实际上是相同的 - 将对象解析为int...
但是后来我也尝试传递 Integer:valueOf 并且它也被接受了 - 所以我明白有几个选项可以传递给 mapToInt,这回答了我的问题...
1)mapToInt 函数的主要目的是将当前流转换为 Intstream,在此基础上可以执行其他 Integer 操作,如 sum、Min、max 等
它是泛型,你永远无法预测输入是什么,在你的情况下它是 String,它可能是 double 、long 或其他东西。 开发人员负责显式转换。
您可以编写自己的函数,在本例中是 function