通用和流:如何将其制成``streamTuple :: new`语句''

  • 本文关键字:streamTuple new 语句 java generics
  • 更新时间 :
  • 英文 :


我在一个小库上工作,该库模拟流中的多价返回值。为此,我希望能够使用StreamTuple::new而不是StreamTuple::createid -> new StreamTuple<>(id, id)。我尝试了各种修改,但是我的通用fu还不够好,无法弄清楚如何更改源以允许。

public class StreamTuple<L, R> {
    protected final L left;
    protected final R right;
    public StreamTuple(L left, R right) {
        this.left = left;
        this.right = right;
    }
    /**
     * Suitable for method::references.  Value is set to id.
     */
    public static <L> StreamTuple<L, L> create(L left) {
        return new StreamTuple<>(left, left);
    }
    ....

调用代码段:

    Map<String, String> m = Stream.of("1", "2", "3")
//          .map(StreamTuple::create)
            .map(id -> new StreamTuple<>(id, id))
            .collect(toMap(StreamTuple::left, StreamTuple::right));

建议?还是无法完成?


编辑:我想要一个仅采用一个参数并返回流tuple的额外构造函数,其中l和r是相同的类型。当前的代码不能反映这一点,因为它是前一段时间,我无法使它起作用,我认为我已经复制了它。我只能找出如何提供L/R之一,这使另一个打开。如何为此编写单个参数构造函数?

您是否考虑过扩展StreamTuple以定义单个参数构造函数?

 Map<String, String> m = Stream.of("1", "2", "3")
.map( UnaryStreamTuple<String>::new )
.collect( Collectors.toMap(UnaryStreamTuple::left, UnaryStreamTuple::right) );
public class UnaryStreamTuple<T> extends StreamTuple<T, T> {
    public UnaryStreamTuple(T left) {
        super(left, left);
    }
    public UnaryStreamTuple(T left, T right) {
        super(left, right);
    }        
}

无法使用构造函数来执行此操作,因为没有办法指定参数是LR的子类型(即conjunction/controction/dutrosection(。该语言具有用于此要求的构造,但是不允许使用类型变量之间的相交:

// not allowed (causes a compilation error)
//                 vvvvv
public <LR extends L & R> StreamTuple(LR val) {
    this.left = val;
    this.right = val;
}

可能会在未来版本的Java中起作用。

您必须使用工厂方法,或者我想是Tsolakp建议的。我认为工厂更有意义。

流的 map方法需要一个 Function,它准确接收一个参数并返回其他内容。

但是,您尝试使用的是 StreamTuple::new,其中2个参数,例如。 BiFunction,所以不匹配。

我想您可以使用flatMap具有每个流元素的两个副本,然后编写一个自定义的Collector来一次收集这些项目2,但这听起来比引用已经匹配的create方法要多得多。

最有效的是您所做的 - 一种恰好采用一个参数并返回所需StreamTuple的工厂方法。

这是由于您两次传递id,因此无法完成。StreamTuple::create是要走的方式。

StramTuple::new将根据接受方法预期的函数接口进行不同的翻译。

期望功能(t-> r(==> :: new转换为 new StreamTuple(t)

期望双方函数(t,u-> r(==> :: new转换为 new StreamTuple(t,u)

期望供应商((( -> r(==> :: new转换为 new StreamTuple()

由于流#映射正在期待一个函数,因此无法转换为2-args构造函数。因此,您的create工厂方法似乎是一个不错的方法。

具有1-arg的配置器(如下(表现得像create方法是不可能的

public StreamTuple(L both) { //will fail compilation
    this.left = both;
    this.right = both;
}

但是,由于您想要一个1-arg构造函数,其参数必须分配给R和L,因此您有2个选项:1(一个延伸另一个(例如R分配给L(

public class StreamTuple<L, R extends L> {
    protected final L left;
    protected final R right;
    public StreamTuple(R both) {
        this.left = both;
        this.right = both;
    }
}

2(如果r和l无关,则需要在getter上进行铸件的对象:

public class StreamTuple<L, R> {
    protected final Object left, right;
    public StreamTuple(Object o) {
        this.left = this.right = o;
    }
    public <L> L getLeft() { return (L) left; }
    public <R> R getRight() { return (R) right; }
}

最新更新