2017-01-24 22 views
0

私は立ち往生しています、私はこれを行う方法はありません。次利用可能なID

次の利用可能なIDを取得したいと考えています。 [ID:1,ID:2,ID:3]がある場合、findId()4(次に使用可能なID)を返します。

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

通常、IDを連続させることには意味がありません。とにかくあなたの質問revalesとしてあなたのIDシーケンスには常に穴があります。現代のコンピュータには、大きな睡眠タイプに対処するための十分な記憶があり、長さを制限する必要はありません。また、IDを再利用することで、データベースなどで永続化されたときに、シード効果が発生する可能性があります。したがって、あなたはホメオパシー改善のためにコンピュータのCPU時間をウエストしてはいけません... –

+0

次のID、次のIDは受け取りません – Max604

+0

どうすればいいですか@TimothyTruckle – Max604

答えて

0

私が正しく理解している場合、すべてのその処理の後、areas.get(i-1).getId()にはIDが「不足していない」されている場合iに等しくされる、1から何までのintを返します。
対応するIDが見つからない場合はi、最後に見つかった場合は次のIDだけを返します。
その場合は:

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

forの範囲外であるため、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()'を返すと、リストの最後のIDが返されます。次のIDは返されません。繰り返しIDが返されます。 – walen

+0

@walenありがとう、編集されました。 –

1

あなたのコード内の主な問題は、そのif/elseであなたはどんな、ループの最初の繰り返しで1または2のいずれかを返さないということです。それを修正する方法については、他の回答を参照してください。

しかし、ソートしてから領域を反復するのではなく、すでに取り込んだIDをSetに保存して、IDを繰り返して、そのIDのセットにないIDを返します。

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のわずかO(N)(N Nログ)です。

しかし、コメントで指摘されているように、最初にIDを再利用するのは最良の方法ではないかもしれません。代わりに、ちょうどmax IDを得ることができます(リスト全体をソートする必要はありません)。

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

単純なfor()ループで問題が発生する人はほとんどが、現在のスキルセットを超えている可能性があるため、StreamsおよびOptionalalsを使用する答えは無視されます。しかし、私はあなたの最後の段落の解決策が気に入っています。 +1。 – walen

+0

@walen OPは元々の質問ですでにJava 8を使用していましたので、それは問題ありません。もちろん、ループや条件を使用して、さらにいくつかの行で同じことを行うことができます。 –

+0

Tbhだからこそ、私はほとんど何がカバーされていたのか知​​っていません。少し深く使われた概念を説明するリンクを知っていますか? – Max604

関連する問題