3 ms·
Sooooo.... A bit more involved than what you describe but I managed to do that: public <A, B, T extends Iterable<A>, R extends Iterable<B>> R process(T inp
by p2t2p 6y ago
Sooooo.... A bit more involved than what you describe but I managed to do that:
public <A, B, T extends Iterable<A>, R extends Iterable<B>> R process(T input, Function<? super A, ? extends B> transformer,
Function<Iterable<B>, R> helper) {
return helper.apply(StreamSupport.stream(input.spliterator(), false)
.map(transformer)
.collect(toList()));
}
@Test
public void testProcess() {
Iterable<Integer> ints = process(Arrays.asList("1", "2", "3"), Integer::parseInt, identity());
System.out.println(ints);
}
Outputs nicely integers nicely converted from strings:
[1, 2, 3]
:-P
`identity()` is a static import of `Function.identity()`
- p2t2p 6y agoThe only caveat is that if you change `Iterable<Integer>` to say `Iterable<String>` the compilation error becomes a bit weird in that it says you provide `Iterable<Object>` while `Iterable<String>` is requested. But you do get compile time check after all.
- mrkeen 6y agoT is not R though. I want to preserve the static type information such that if I call: baz(bar(foo(t, f))); T<A> should go into foo(..) and come out (e.g. as T<B>) such that I can then call bar(..) on it. But in this case it leaves foo(..) as R extends Fooable, which is not something I can pass into bar(..).
- vimax 6y agoThat's close, but not quite what I want. The Iterator example starts to break down, but I want to pass in a subclass of Iteratable and get that subclass back. class SpecialIterator<R> extends Iterator<R>{} SpecialIterator<String> strings =...; SpecialIterator<Integer> ints = process(string, magicFunc); The Iterator example starts to break down, so here's a more concrete example: I have 3 classes: AbstractTester, StringTester, and ListTester class AbstractTester<R, T extends AbstractTester<R, ? super T>> class StringTester<R> extends AbstractTester<R, StringTester<R>> class ListTester<R, T extends AbstractTester<R, ? super T>> I want to make a method in AbstractListTest like this: public <Z> T<Z> convert(Z z) I have supporting code in my classes to create an return an instance of type T<Z>, but I cannot express the type T<Z> in the type system. The type parameter T can extend something with a type parameter, and be passed a type with a type parameter, but it cannot be defined to have a type parameter itself. This is for a fluent api framework, where I need the compiler to know the type T<Z> without casting I can do something like this: public <Z, Y extends AbstractTester<Z, ? super T>> Y convert(Z z); but that will return an AbstractTester<Z> which can be cast to a StringTester<Z>, but the compiler does not know it is a StringTester<Z> A subclass of AbstractTester is not required to have any type parameters itself. Converting a T to a T<Z> would not be legal for a T without a type parameter. To do what I want, Java would need to add a new type bounds operator to restrict a type parameter to subclasses with a particular type parameter. Java would need to allow me to define ListTester like this to restrict T to only subclasses with a type parameter: class ListTester<R, T<_> extends AbstractTester<_, ? super T<_>> I'd love to be wrong, and would be very grateful to find a way to do this.