Java создать Iterable <? расширяет SuperClass> из Iterator <SubClass> без предупреждения

Как правильно создать 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);
}

Но я получаю предупреждение Непроверенный состав. Есть ли способ сделать это чисто?

Здесь две очевидные проблемы: String.join принимает Iterable, а не Iterator. Кроме того, почему вы используете лямбда-выражение поставщика?

ernest_k 15.01.2019 19:54

Ваш вопрос является ответом на первую заявленную вами "проблему": lambdafaq.org/how-can-i-turn-an-iterator-into-an-iterable

Ricola 15.01.2019 21:34
.stream().collect(joining(" "))
Boris the Spider 15.01.2019 21:44

@BoristheSpider .stream() чего? words.stream() будет не в том порядке, в котором я ожидал. Вы можете создать поток из Iterable с .spliterator(), но вам снова понадобится Iterable. Во всяком случае, метод .join() был здесь как раз для примера.

Ricola 15.01.2019 21:53

Не уверен, почему вы думаете, что вы не можете создать Stream из Iterator - stackoverflow.com/questions/24511052/…. Делайте это и не создавайте несовместимые реализации Iterable; используя лямбды или иначе.

Boris the Spider 16.01.2019 21:09
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
5
311
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Хорошо, я нашел то, что искал, и на самом деле это было довольно просто:

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

Нет необходимости использовать подстановочный знак.

Что ж, приятно, что ты наконец решил принять свой ответ. :-)

ETO 04.09.2019 20:54

Было бы интересно услышать ваши аргументы против моего первого решения (за которое проголосовало сообщество).

ETO 04.09.2019 20:56

@ETO: Я никогда не говорил, что ваш ответ был плохим (я его поддержал). Просто это было именно то, что я искал и отвечал на исходный вопрос: Как правильно создать Iterable <? расширяет SuperClass> из Iterator <SubClass>?. В моем вопросе я просто неправильно его закидывал.

Ricola 09.09.2019 12:18

Не называйте свой ответ правильный путь. Пусть сообщество решит, что правильно.

ETO 09.09.2019 18:30

Во-первых, я не получаю репутацию, принимая свой собственный ответ. Во-вторых, выбор того, какой ответ будет принят, предоставляется тому, кто задает вопрос, который он выбирает на основе того, что он искал. Так происходит в stackoverflow, и я иногда видел, что принимается плохой / неполный ответ. Это не идеально, но именно поэтому у вас есть положительные голоса для ранжирования ответов. В-третьих, я отредактировал свой ответ, чтобы не называть его «правильным способом», поскольку вы были правы насчет правильной формулировки.

Ricola 12.09.2019 15:42

Вы также можете попробовать:

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));
}

Другие вопросы по теме