我正在开发一个小型库,它在Streams中模拟多值返回值。为了使其运作良好,我希望能够使用import UIKit
class URLRequestGroup {
var dispatchGroup: DispatchGroup
init(dispatchGroup: DispatchGroup) {
self.dispatchGroup = dispatchGroup
}
init() {
self.dispatchGroup = DispatchGroup()
}
func beginURLRequest(urlRequest: URLRequest,
completionHandler: @escaping (Data?, URLResponse?, Error?) -> ()) {
let urlSession = URLSession(configuration: URLSessionConfiguration.default)
// Enter the dispatchGroup manually
dispatchGroup.enter()
urlSession.dataTask(with: urlRequest, completionHandler: { [weak self] data, urlResponse, error in
completionHandler(data, urlResponse, error)
// Leave this dispatchGroup.
self?.dispatchGroup.leave()
}).resume()
}
}
let group = URLRequestGroup()
group.beginURLRequest(urlRequest: URLRequest(url: URL(fileURLWithPath: "http://www.example.com")), completionHandler: { data, urlResponse, error in
print(data?.count ?? 0)
})
// Put any other request here.
group.dispatchGroup.wait()
代替StreamTuple::new
或StreamTuple::create
。我尝试了各种修改,但是我的generics-fu不足以弄清楚如何更改源代码来实现这一点。
id -> new StreamTuple<>(id, id)
调用代码段:
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);
}
....
连连呢?或者不能这样做?
编辑:我想要一个额外的构造函数,它只接受一个参数并返回一个StreamTuple,其中L和R是相同的类型。目前的代码并没有反映出这一点,因为它不久之前我无法使它工作,我想我复制了它。我只能找到如何提供一个L / R并让另一个开放。如何为此编写单个参数构造函数?
答案 0 :(得分:2)
您是否考虑过扩展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);
}
}
答案 1 :(得分:1)
由于您传递id
两次,因此无法完成。 StreamTuple::create
是要走的路。
答案 2 :(得分:1)
Stream https://issues.apache.org/jira/browse/FLINK-8485需要一个Function
,它只接受一个参数并返回其他内容。
但是,您尝试使用的是StreamTuple::new
,并且它包含2个参数,例如BiFunction
,因此不匹配。
我想你可以使用flatMap
来获得每个流元素的两个副本,然后map
method一次收集这些项目2,但这听起来比引用你的{{{{{{ 1}}方法,已匹配。
最有效的是你所做的 - 一种工厂方法只需一个参数并返回所需的create
。
答案 3 :(得分:1)
StramTuple::new
将根据接受方法所期望的FunctionalInterface进行不同的翻译。
期待Function(T - > R)==&gt; :: new转换为new StreamTuple(t)
期待BiFunction(T,U - > R)==&gt; :: new转换为new StreamTuple(t,u)
期待Supplier(() - &gt; R)==&gt; :: new转换为new StreamTuple()
由于Stream#map需要Function,因此无法转换为2-args构造函数。所以你的create
工厂方法似乎是一个很好的方法。
有一个1-arg构造函数(如下所示)的行为类似于create
方法是不可能的,因为编译器会抱怨因为R没有绑定
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; }
}
答案 4 :(得分:1)
使用构造函数无法做到这一点,因为没有办法指定参数是L
和R
的子类型(即连接/交集)。该语言具有这种要求的构造,但不允许类型变量之间的交集:
// not allowed (causes a compilation error)
// vvvvv
public <LR extends L & R> StreamTuple(LR val) {
this.left = val;
this.right = val;
}
然而,这可能适用于Java的未来版本。
你必须使用工厂方法,或者我想,tsolakp建议使用什么。我认为工厂更有意义。