我被困了,我不知道怎么做。
我想获得下一个可用的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;
}
答案 0 :(得分:1)
您的代码中的主要问题是,使用if/else
,您将在循环的第一次迭代中返回1
或2
,无论如何。请参阅其他答案以了解如何解决此问题。
然而,我不是对区域进行排序然后迭代,而是将已经采用的ID存储在Set
中,然后迭代可能的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(n)而不是O(n log n)来排序列表。
但是,正如评论中指出的那样,重用ID可能不是最好的方法。相反,您可以获取max
ID(同样,无需对整个列表进行排序)并添加一个。
public int findId() {
return getAreas().stream().mapToInt(Area::getId).max().orElse(0) + 1;
}
答案 1 :(得分: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;
}
答案 2 :(得分:0)
如果我理解正确,在完成所有处理之后,areas.get(i-1).getId()
会返回从{1到1}的int
,如果没有ID“丢失”,则等于i
。<登记/>
因此,如果缺少相应的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;
}