Java create Iterable<? extends SuperClass> from Iterator<SubClass> without warning

Viewed 376

How to properly create an Iterable<? extends SuperClass> from Iterator<SubClass>?

Let's just say that I have an Iterator<String> and I want to use a method that takes an Iterable<? extends CharSequence>. This is of course not possible:

private String foo(Deque<String> words) {
    Iterator<String> iterator = words.descendingIterator();
    return String.join(" ", () -> iterator);
}

The only way I found to make it compile was with

private String foo(Deque<String> words) {
       Iterator<? extends CharSequence> iterator = words.descendingIterator();
       return String.join(" ", () -> (Iterator<CharSequence>) iterator);
}

But I get an Unchecked cast warning. Is there a way to do this a clean way?

2 Answers

You could try also:

private String foo(Deque<String> words) {
    return String.join(" ", (Iterable<String>) words::descendingIterator);
}

But for general case it would be better to create an utility method:

public static <T> Iterable<T> iterable(Iterable<T> iterable) {
    return iterable;
}

Then use it simply like this:

 private static String foo(Deque<String> words) {
    return String.join(" ", iterable(words::descendingIterator));
}

OK I found what I was looking for and it was actually pretty simple:

private String foo(Deque<String> words) {
    Iterator<String> iterator = words.descendingIterator();
    return String.join(" ", (Iterable<String>) () -> iterator);
}

No need to use the wildcard at all.

Related