代码之家  ›  专栏  ›  技术社区  ›  Mohammad Karmi

<r>流<r>映射(函数<?超级T?扩展r>mapper)流

  •  2
  • Mohammad Karmi  · 技术社区  · 6 年前

    我在查看流接口时发现了以下方法:

     <R> Stream<R> map(Function<? super T, ? extends R> mapper);
    

    我找不到任何理由为什么?扩展r“而不是r:

     <R> Stream<R> map(Function<? super T, R> mapper);
    

    那么如果我像上面那样做会有什么区别呢?不是“?”是我传递的r变量吗?它会延长r我找不到原因。

    3 回复  |  直到 6 年前
        1
  •  6
  •   ernest_k Petronella    6 年前

    它使用 ? extends R 允许 map 声明为返回 R

    例如,给定此流:

    Stream<Number> numberStream = Stream.of(1, 2L);
    

    在下面 地图 呼叫, R Number ,但函数的类型是 Function<Number, Integer> :

    Function<Number, Integer> function = n -> Integer.valueOf(n.intValue());
    Stream<Number> numberStream2 = numberStream.map(function); //would have failed
    

    如果没有 ?扩展R 然后 function 会是个无效的论点( Function<Number, Number> 会被要求的)

        2
  •  0
  •   Laohyx    6 年前

    ? extends R 意味着您可以通过 R ,即 R .

    所以map函数可以生成 R R's subclass 结果。这是合理的。

    例如,如果我们有这些类: Animal , Groose (extends Animal) , Egg Function<Egg, Groose> hatching

    您可以编写以下代码:

    List<Egg> eggs = getEggs();
    List<Animal> myPets = eggs.stream().map(hatching)....
    

    你可以看到 map 功能需要 动物 类型( R ),但你的映射程序返回 Groose 类型(即 ?扩展R )。如果 地图 函数写入为 <R> Stream<R> map(Function<? super T, R> mapper); ,必须添加另一个 匍匐 动物 .

    你可以参考 this answer 并理解 <? extends T> .

        3
  •  0
  •   YK S    6 年前

    在Java中泛型是不变的,这意味着即使S扩展P,下面的代码也会抛出编译错误。

    List<S> list1 = neww ArrayList<>();
    List<P> list2 = list1 ; // compile error
    

    但如果你有列表,你可以做以下事情:

    List<S> list1 = neww ArrayList<>();
    List<? extends P> list2 = list1 ;
    
    推荐文章