2017-02-20 6 views
-1

Я пытаюсь выполнить leetcode - Учитывая массив целых чисел, каждый элемент появляется три раза, кроме одного, который появляется ровно один раз. Я пытаюсь использовать потоки, чтобы сделать это, чтобы я мог практиковать Java 8. Но я продолжаю получать разные ошибки. Я хотел бы использовать findFirst(), как только я нахожу элемент, который мне не нужно продолжать итерации по HashMap.«Переменные должны быть окончательными» ошибки компилятора при попытке использовать Java 8 streams API

public class Solution { 
    public int singleNumber(int[] nums) { 

     HashMap<Integer, Integer> map = new HashMap<>(); 

     for (int num: nums){ 
      if (map.containsValue(num)) 
      map.put(num, map.get(num) +1); 
      else 
      map.put(num, 1); 
     } 

     map.forEach((k, v) -> { 

      if (v == 1) 
       return k; 
     }); 

    } 
} 

Когда я бегу выше я получаю

Line 13: error: no suitable method found for forEach((k,v)->{ i[...] k; }) 

Когда я пытаюсь

public class Solution { 
    public int singleNumber(int[] nums) { 

     HashMap<Integer, Integer> map = new HashMap<>(); 

     for (int num: nums){ 
      if (map.containsValue(num)) 
       map.put(num, map.get(num) +1); 
      else 
       map.put(num, 1); 
     } 

     Map<Integer, Integer> answer= map.entrySet().stream() 
       .filter(p -> p.getValue() == 1) 
       .findFirst() 
       .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue())); 
     return answer.getValue(); 
    } 
} 

я cannot resolve method collect. Если я удаляю линию сбора, то он жалуется на необходимость точки с запятой.

Когда я пытаюсь

int number = 0; 
    map.forEach((k, v) -> { 

     if (v == 1) 
      number = k; 
    }); 
    return number; 

Я получаю Line 16: error: local variables referenced from a lambda expression must be final or effectively final ожидаемый ответ

Но если я объявляю номер, чтобы быть окончательным, то он говорит, что я не могу назначить его.

Когда я пытаюсь (в последней строке в потоке)

.collect(Collectors.groupingBy(i -> i));

я получаю

Line 15: error: cannot find symbol: method collect(Collector>>)

Если удалить последнюю строку потока и изменить рядом с последней строки в

.findFirst());

Тогда я получаю

Line 14: error: ';' expected this is for two or three).

Если я

.findFirst();

Тогда я получаю

Line 14: error: incompatible types: Optional> cannot be converted to Map

+0

«продолжайте получать разные ошибки» ... какие ошибки? быть конкретной? опубликуйте точно код, который терпит неудачу, и сообщите нам, что происходит с ошибкой. пока у вас это не получится, вопрос не в тему – nhouser9

+0

В Entry Entry нет метода collect(). Вы выполняете итерацию и Set of Entry (EntrySet) – Rondo

+0

Если я удалю сбор(), то я получаю Необязательный не может быть преобразован в Map.Line 14: ошибка: несовместимые типы: Необязательный > не может быть преобразован to Map Ожидаемый ответ – Sam

ответ

1

forEach не ожидает, что тип возвращаемого значения, это "потребляя" функция, следовательно, ваша ошибка.

Чтобы ответить на ваш вопрос о том, что «локальные переменные, на которые ссылается выражение лямбда, должно быть окончательным или эффективно окончательным» в Java, вы не можете присвоить значение переменной с именем number снова изнутри лямбды (или даже за пределами лямбда) , Это ограничение того, как Lambda были реализованы. Как говорится в сообщении, он должен быть помечен как final, или вы никогда не назначаете другое значение number после того, как оно было инициализировано (фактически окончательно).

В качестве отправной точки для альтернативного решения, попробуйте использовать groupingBy

Map<Integer, List<Integer>> map = Stream.of(1, 1, 1, 2, 3, 3, 3) 
       .collect(Collectors.groupingBy(i -> i)); 

дает вам следующие

{1=[1, 1, 1], 2=[2], 3=[3, 3, 3]} 

Редактировать

Вместо зацикливания с Foreach, мы можем использовать другой поток для возврата вашего int вы хотите (т.е. 2).

Учитывая выход карту выше вы хотите отфильтровать и сохранить только запись в карте, что есть только одно значение, так это сделать следующий

List<List<Integer>> onlyOne = map.values().stream() 
    .filter(v -> v.size() == 1) 
    .collect(Collectors.toList()); 

дает Вам следующую единственную запись

[[2]] 

Теперь все, что вам нужно сделать, это извлечь значение 2

Отказ от ответственности: существует множество способов решить эту проблему с помощью str eams, я пытаюсь помочь вам думать функционально с этим примером, а не дать вам однострочное решение, которое вы, возможно, не понимаете.

+0

Я изменил фамилию в потоке на groupingBy и получил эту ошибку Ваш ответ Строка 15: ошибка: не удается найти символ: метод collect (Collector >>) Также Я не могу объявить эту числовую переменную в выражении лямбда, а затем вернуть ее. Существует только один int, что мне нужно вернуть не список hashmap. – Sam

+0

Привет @Sam взгляните на мое редактирование и ответьте, если у вас есть еще вопросы – Brad

Смежные вопросы