2017-01-24 2 views
0

Я застрял, я не знаю, как это сделать.Доступный Следующий ID

Я хочу получить следующий доступный идентификатор. Если есть [ID:1,ID:2,ID:3], findId() вернет 4 (следующий доступный идентификатор).

Если ID:2 удален, мы получаем [ID:1,ID:3], поэтому теперь он должен вернуть 2.

Любая помощь, пожалуйста!

public int findId() { 
    if (getAreas().isEmpty()) 
     return 1; 
    List<Area> areas = new ArrayList<>(getAreas()); 
    areas.sort(Comparator.comparingInt(AutoPayArea::getId)); 

    for (int i = 1; i <= areas.size(); i++) { 
     if (i < areas.get(i - 1).getId()) { 
     return i; 
     } else { 
     return i + 1; 
     } 
    } 
    return -1; 
} 
+3

Обычно нет смысла хранить идентификаторы последовательно. По мере того как ваш вопрос будет изменяться, в любом случае все равно будут дыры в вашей идентификационной последовательности. И у современных компьютеров достаточно памяти для работы с большими типами nunber, так что нет необходимости ограничивать их длины. Кроме того, повторное использование идентификаторов может иметь эффект seide, когда они сохраняются в базе данных или около того. Поэтому вам не следует настраивать время процессора компьютера только для гомеопатического улучшения ... –

+0

следующий идентификатор, следующий ID не принят – Max604

+0

Как это сделать @TimothyTruckle – Max604

ответ

0

Если я правильно понял, после всей этой обработки, areas.get(i-1).getId() возвращает int в диапазоне от 1 до любой другой, который будет равен i, если нет ID не «отсутствует».
Итак, вы хотите вернуть i, если отсутствует соответствующий идентификатор, или только следующий идентификатор после последнего найденного.
Если это так:

public int findId() { 
    if (getAreas().isEmpty()) 
     return 1; 
    List<Area> areas = new ArrayList<>(getAreas()); 
    areas.sort(Comparator.comparingInt(AutoPayArea::getId)); 

    for (int i = 1; i <= areas.size(); i++) { 
     if (i < areas.get(i - 1).getId()) { 
     return i; // "i" is missing, return that 
     } 
    } 
    // If we haven't returned yet, it means that no ID is missing, 
    // so just return the next one, which is areas.size()+1 (which just happens to be "i" again but it's out of scope now). 
    return areas.size()+1; 
} 
+0

Не могу вернуть i, так как он выходит из области действия. –

+0

Упс! Исправлено, спасибо! – walen

0
public int findId() { 
    if (getAreas().isEmpty()) 
     return 1; 
    List<Area> areas = new ArrayList<>(getAreas()); 
    areas.sort(Comparator.comparingInt(AutoPayArea::getId)); 

    for (int i = 0; i < areas.size(); i++) { 
     if (areas.get(i).getId > (i+1)) { 
      return i+1; 
     } 
    } 
    return areas.size()+1; 
} 
+1

Это неправильно. Возврат 'areas.size()' вернет последний идентификатор в списке, а не следующий, и вы получите повторные идентификаторы. – walen

+0

@walen спасибо, отредактирован. –

1

Основная проблема в вашем коде является то, что с этим if/else не будет возвращать 1 или 2 в первой итерации цикла, независимо от того, что. См. Другие ответы, как исправить это.

Однако вместо сортировки, а затем итерации областей я просто сохранил уже взятые идентификаторы в Set, а затем перечислил возможные идентификаторы и вернул первый, который еще не был в этом наборе.

public int findId() { 
    Set<Integer> ids = getAreas().stream() 
      .map(Area::getId) 
      .collect(Collectors.toSet()); 
    return IntStream.iterate(1, n -> n + 1) 
      .filter(n -> ! ids.contains(n)) 
      .findFirst().getAsInt(); 
} 

Логика в таком подходе немного проще и менее склонны к ошибкам «разовым», и сложность только О (п) вместо O (N журнал N) для сортировки списка.

Однако, как указано в комментариях, повторное использование идентификаторов может быть не лучшим выбором в первую очередь. Вместо этого вы можете просто получить идентификатор max (опять же, не нужно сортировать весь список) и добавить его.

public int findId() { 
    return getAreas().stream().mapToInt(Area::getId).max().orElse(0) + 1; 
} 
+0

Большинство людей, имеющих проблемы с простым циклом for(), игнорируют ответ, который использует Streams и Optionals, потому что он, вероятно, находится за пределами их текущего набора навыков. Но мне нравится решение в вашем последнем абзаце. +1. – walen

+0

@walen OP уже использовал некоторую Java 8 в исходном вопросе, поэтому, хотя это должно быть хорошо. Но, конечно же, это можно сделать еще в нескольких строках с использованием циклов и условий. –

+0

Tbh вот почему, и я почти не знаю, что было покрыто, знаете ли вы какие-либо ссылки, которые объясняют понятия, используемые немного глубже, вместо этого я буду отмечать это. – Max604

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