Stream.toArray(Book[]::new) 如何知道数组有多少个元素以及“Book[]::new”的实现在哪里?

问题描述 投票:0回答:1

我正在尝试理解方法引用,但我不知道如何使用这个“

Book[]::new
”来创建一个 具有正确数量元素的数组。

Book[] arrayBook = stBooks.toArray(Book[]::new);

为了在使用第二个和第三个选项时创建数组,我必须指定一个接收 int 并返回新数组的函数接口。

但是,在第一个选项中我不知道实现在哪里以及在哪里指定的数量 将具有数组的元素。我认为它为每个 Stream 元素创建一个新的数组元素 但如果我理解得很好,你必须提供实现,而“

Book[]::new
”没有它。

Book book1 = new Book("ESDLA");
Book book2 = new Book("Harry Potter");
Stream<Book> stBooks = Stream.of(book1, book2);


// 1. Method References
Book[] arrayBook = stBooks.toArray(Book[]::new);

// 2. With Lambda Implementation
Book[] arrayBook1 = stBooks.toArray( (numElements) -> new Book[numElements] );

// 3. With Implementation
Book[] arrayBook2 = stBooks.toArray( new IntFunction<Book[]>() {

    @Override
    public Book[] apply(int numElements) {
        return new Book[numElements];
    }
});
java arrays java-stream functional-interface method-reference
1个回答
5
投票

这是语言规范中的特殊情况:

如果方法引用表达式的形式为

ArrayType::new
,则考虑单一名义方法。该方法有一个
int
类型的参数,返回
ArrayType
,并且没有 throws 子句。如果 n = 1,这是唯一可能适用的方法;否则,没有可能适用的方法。

还有

如果形式为

Type[]^k :: new
(k ≥ 1),则调用方法的主体与
new Type [ size ] []^k-1
形式的数组创建表达式具有相同的效果,其中
size
是调用方法的单个参数。 (符号
[]^k
表示 k 个括号对的序列。)

所以你想要找到的“实现”隐藏在Java编译器的某个地方,因为它都是“编译器魔法”。

© www.soinside.com 2019 - 2024. All rights reserved.