Нужна помощь в понимании того, как найти getLength() итерируемого

У меня проблемы с пониманием того, как я не могу найти getLength() итерации в моей домашней работе. Предполагается, что класс представляет собой «набор инструментов» с полезными методами для работы с итерируемыми объектами и итераторами.

   /** Computes the length of an Iterable.
       The length of an Iterable is the total number of entries it returns.
   public static <T> int getLength(Iterable<T> iterable)
   {
      int numEntries = 0;
      while(iterable.hasNext()) {
         numEntries++;
         iterable.next();
      }
      return numEntries;
   }

Это то, что у меня есть сейчас, но я получаю это

Toolkit.java:30: error: cannot find symbol
      while(iterable.hasNext()) {
                    ^
  symbol:   method hasNext()
  location: variable iterable of type Iterable<T>
  where T is a type-variable:
    T extends Object declared in method <T>getLength(Iterable<T>)

Вы должны вызвать Iterable.iterator()

shmosel 31.10.2022 07:45

^ И сохраните полученный Iterator в переменной, чтобы вы могли использовать его в цикле while.

Slaw 31.10.2022 07:55

Кроме того, я не знаю, была ли вам предоставлена ​​сигнатура метода, но параметр типа (<T>) не обязателен. Метод не зависит от типа элементов в итерируемом объекте, поэтому параметр метода может быть просто Iterable<?>.

Slaw 31.10.2022 08:03

Или for (T dummy : iterable) numEntries++;.

user17233545 31.10.2022 08:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуй это:

public static int size(`Iterable` data) {

    if (data instanceof Collection) {
        return ((Collection<?>) data).size();
    }
    int counter = 0;
    for (Object i : data) {
        counter++;
    }
    return counter;
}
Ответ принят как подходящий

Это концептуально не работает. Концепция Iterable заключается исключительно в том, что вы можете попросить его создать итераторы. Именно итератор отвечает за все hasNext и next. Итераторы не гарантируют, что они будут возвращать один и тот же итератор каждый раз, когда вы запрашиваете итератор; вы можете вызвать iterator() и увидеть 500 элементов, а затем снова вызвать и увидеть 512. У вас нет особых гарантий, поэтому «запросить длину итерации» не подлежит ответу. Для некоторых конкретных известных итераций, таких как ArrayList, вы можете ответить на вопрос, и это будет легко сделать, но есть итерации, для которых вы не можете этого сделать. Различные итерации могут быть запрошены только один раз для iterator(), например, что-либо, представляющее концепцию потоковой передачи (скажем, ваша итерация — это пожарный шланг всех сообщений телеграммы, отправленных на канал телеграммы).

Другими словами, это глупая домашняя работа; кто бы это ни дал, не до конца понимает, что представляют собой эти понятия. Этот код будет работать для некоторых итераций, но не будет работать для многих других, либо делая недействительной возможность итерации через него после вызова этого, либо сбой, либо давая неправильный ответ - это именно то, что вы написали, за исключением того, что сначала создайте итератор. Пока мы здесь, давайте избавимся от этого бесполезного <T>, он нам не нужен:

public static int getLength(Iterable<?> iterable) {
  int numEntries = 0;
  var iterator = iterable.iterator();
  while(iterator.hasNext()) {
    numEntries++;
    iterator.next();
  }
  return numEntries;
}

Однако, учитывая, что на самом деле это не «работает», я бы написал что-то совсем другое:

public static int getLength(Iterable<?> iterable) throws IllegalArgumentException {
  if (iterable instanceof Collection<?>) return ((Collection<?>) iterable).size();
  throw new IllegalArgumentException("I don't know how to obtain the size for an iterable of type " + iterable.getClass());
}

Действительно, ошибка во всей установке является аргументом. Так должно было быть Collection<?> все это время. Почти все итерации, которые вы когда-либо встречали, реализуют Collection — основное различие между Iterable и Collection в том, что вы можете спросить у коллекции, насколько она велика. Iterable существует именно потому, что он представляет собой тип, в котором «могу ли я узнать, насколько вы велики» не является обязательной способностью. Еще раз подчеркнув, насколько глупо это домашнее задание.

Не стесняйтесь направлять своего учителя к этому ответу. Если это общий учебник или книга, выбросьте ее и возьмите другую.

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