stream.collect与stringbuilder一起工作,但自定义类不工作

pobjuy32  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(294)
// S#1. stream works with StringBuilder 
    System.out.println( 
            Stream.of("a", "b", "c", "d", "ef", "ghi", "j")
                    .collect(StringBuilder::new,
                            StringBuilder::append,
                            StringBuilder::append)
                    .toString()
    );

    // S#2. stream works fine with Int 
    // my custom class that conforms to arg types of collect method
    // method signature: collect(Supplier, accumulator, combiner)
    Int anInt = new Int();
    System.out.println(
            Stream.of("a", "b", "c", "d", "ef", "ghi", "j")
                    .collect(() -> anInt, Int::accumulator, Int::combiner)
                    .total
    );
    class Int {
      int total;
      static void accumulator(Int result, String str) { result.total += str.length(); }
      static void combiner(Int a, Int b) { a.total += b.total; }
    }

    // S#3. compiler error with Int2 
    // custom class I created which has method accumulator(String) similar to StringBuidler append(String)
    // StringBuilder::append (used as above in S#1)
    Int2 int2 = new Int2();
    System.out.println(
            Stream.of("a", "b", "c", "d", "ef", "ghi", "j")
                    .collect(() -> int2, int2::accumulator, int2::combiner)
    );
    class Int2 {
      void accumulator(String s) {}
      void combiner(Int2 b) {}
    }

但是我想知道stringbuilder版本的代码是如何编译的,而s#3(int2版本)却没有。stringbuilder扩展自charsequence、abstractstringbuilder类。是不是因为我的自定义类(int2)中缺少的这种层次关系才起作用
非常感谢你的帮助。

um6iljoc

um6iljoc1#

比较您使用 StringBuilder 方法,以及你使用 Int2 方法:

.collect(StringBuilder::new,
    StringBuilder::append,
    StringBuilder::append)

.collect(
    () -> int2, 
    int2::accumulator, 
    int2::combiner)

显然,它们有不同的形式。 int2::accumulatoraccumulator 方法的特定示例 Int2 打电话 int2 . StringBuilder::append 但是,指 append 方法。这些是不同类型的方法引用。有关不同类型的方法引用的详细信息,请参阅本页中的“各种方法引用”。
您应该使用:

.collect(
    Int2::new, 
    Int2::accumulator, 
    Int2::combiner)
``` `int2::accumulator` 在文档中称为“对特定对象的示例方法的引用”,它是指采用 `String` 返回 `void` ,因此可以将其传递到 `Consumer<String>` . 然而, `collect` 期望 `BiConsumer<Int2, String>` 作为第二个论点。
因为 `Int2::accumulator` 不引用的特定示例 `Int2` . 它在文档中称为“对特定类型的任意对象的示例方法的引用”。它表示一个函数,该函数接受 `Int2` 作为它的第一个参数,除了 `accumulator` 通常接受。这就是为什么你可以通过 `Int2::accumulator` 相反。类似的解释也适用于 `Int2::combiner` .
这是不言而喻的,但是您的方法是空的,所以它在运行时不会做任何事情。

相关问题