Как правильно создать Iterable<? extends SuperClass> из Iterator<SubClass>?
Скажем так, у меня есть Iterator<String>, и я хочу использовать метод, который принимает Iterable<? extends CharSequence>. Конечно, это невозможно:
private String foo(Deque<String> words) {
Iterator<String> iterator = words.descendingIterator();
return String.join(" ", () -> iterator);
}
Единственный способ, который я нашел, чтобы скомпилировать, был с
private String foo(Deque<String> words) {
Iterator<? extends CharSequence> iterator = words.descendingIterator();
return String.join(" ", () -> (Iterator<CharSequence>) iterator);
}
Но я получаю предупреждение Непроверенный состав. Есть ли способ сделать это чисто?
Ваш вопрос является ответом на первую заявленную вами "проблему": lambdafaq.org/how-can-i-turn-an-iterator-into-an-iterable
.stream().collect(joining(" "))@BoristheSpider .stream() чего? words.stream() будет не в том порядке, в котором я ожидал. Вы можете создать поток из Iterable с .spliterator(), но вам снова понадобится Iterable. Во всяком случае, метод .join() был здесь как раз для примера.
Не уверен, почему вы думаете, что вы не можете создать Stream из Iterator - stackoverflow.com/questions/24511052/…. Делайте это и не создавайте несовместимые реализации Iterable; используя лямбды или иначе.




Хорошо, я нашел то, что искал, и на самом деле это было довольно просто:
private String foo(Deque<String> words) {
Iterator<String> iterator = words.descendingIterator();
return String.join(" ", (Iterable<String>) () -> iterator);
}
Нет необходимости использовать подстановочный знак.
Что ж, приятно, что ты наконец решил принять свой ответ. :-)
Было бы интересно услышать ваши аргументы против моего первого решения (за которое проголосовало сообщество).
@ETO: Я никогда не говорил, что ваш ответ был плохим (я его поддержал). Просто это было именно то, что я искал и отвечал на исходный вопрос: Как правильно создать Iterable <? расширяет SuperClass> из Iterator <SubClass>?. В моем вопросе я просто неправильно его закидывал.
Не называйте свой ответ правильный путь. Пусть сообщество решит, что правильно.
Во-первых, я не получаю репутацию, принимая свой собственный ответ. Во-вторых, выбор того, какой ответ будет принят, предоставляется тому, кто задает вопрос, который он выбирает на основе того, что он искал. Так происходит в stackoverflow, и я иногда видел, что принимается плохой / неполный ответ. Это не идеально, но именно поэтому у вас есть положительные голоса для ранжирования ответов. В-третьих, я отредактировал свой ответ, чтобы не называть его «правильным способом», поскольку вы были правы насчет правильной формулировки.
Вы также можете попробовать:
private String foo(Deque<String> words) {
return String.join(" ", (Iterable<String>) words::descendingIterator);
}
Но для общего случая лучше создать служебный метод:
public static <T> Iterable<T> iterable(Iterable<T> iterable) {
return iterable;
}
Тогда используйте это просто так:
private static String foo(Deque<String> words) {
return String.join(" ", iterable(words::descendingIterator));
}
Здесь две очевидные проблемы:
String.joinпринимаетIterable, а неIterator. Кроме того, почему вы используете лямбда-выражение поставщика?