这是我现在遇到的麻烦部分:
public int getNextID (){
int i;
for(i = 0; i < members.size(); i++){
if(i == members.get(i).getID()){
i++;
}
else if(i != members.get(i).getID()){
System.out.println("Next available ID: " + i);
} else {
System.out.println("Next available ID: " + members.size());
break;
}
}
return i;
}
答案 0 :(得分:0)
对于列表,请使用size()
来获取元素数。(它还会为您提供最后一个但使用1个索引)。
索引从0开始,并在添加或删除元素时自动调整。
因此,您无需手动跟踪索引。
请注意,当您使用方法add(index, element)
添加到列表时,索引应始终小于或等于size()
_ methods return。
List<String> l = new ArrayList<String>();
l.add("a"); //auto index 0
l.add("b"); //auto index 1
l.add("c"); //auto index 2
System.out.println(l.size()); //3 and it's also next_available for add at bottom
l.remove(1);
l.forEach(System.out::println); //a c
System.out.println(l.size()); // 2
System.out.println(l.get(0)); //a
System.out.println(l.get(1)); //c adjusted index from 2 to 1 after remove
l.add(2,"d");
System.out.println(l.size()); //3
l.add(4,"e"); //error java.lang.IndexOutOfBoundsException: Index: 4, Size: 3
请参阅@Sunchezz和@Evan答案以获取完整的解决方案。
答案 1 :(得分:0)
此解决方案从列表中提供了一个新的会员ID,其中所有MemberItem均按ID排序。列表中的项目0必须具有ID0。项目1-> ID 1。 新ID将始终是当前未分配的最低可用ID。
public int getNextID (){
for(int i = 0; i < members.size(); i++){
if(i < members.get(i).getID()){
System.out.println("Next available ID: " + i);
// at this point we know this is the next id.
// we can leave the method and return the next ID.
return i;
}
}
// we did not leave the loop (and method), because all id's are assigned.
System.out.println("Next available ID: " + members.size());
return members.size();
}
如果您喜欢2行Java 8流解决方案,也可以使用以下方法:
public int getNextID() {
Member m = members.stream().filter(member -> member.getID() != members.indexOf(member)).findFirst().orElse(null);
return (m != null ? members.indexOf(m) : members.size());
}
或1行流解决方案:
public int getNextID() {
return members.stream().filter(member -> member.getID() != members.indexOf(member)).findFirst().map(m2 -> members.indexOf(m2)).orElse(members.size());
}
要对您的代码说些什么:
您将i
增加两次。
一次在for
语句中以i++
结尾,在下面的两行再次以i++
结尾。
这样,您将跳过索引1。如果第一个成员具有与索引相同的ID。
适合对三种解决方案之间的时间比较感兴趣的任何人。这是我使用Java1.8的时间:
|----------------------------------------------------------------------|
| 10000 Items, Free Position 9998 | 10000 Items, Free Position 1 |
|----------------------------------------------------------------------|
| Solution1: ~2ms | Solution1: ~0.005ms |
| Solution2: ~65ms | Solution2: ~0.05ms |
| Solution3: ~60ms | Solution3: ~0.06ms |
|----------------------------------------------------------------------|
在机器上执行它的代码。肯定会导致计时结果不同,但是比例应该保持不变。
import java.util.ArrayList;
import java.util.List;
public class Test {
private static List<Member> members = new ArrayList<>();
public static void main(String[] args) {
members = getTestList(10000);
warmUp();
members.remove(9998);
testSolutions();
members.remove(1);
testSolutions();
}
private static void warmUp() {
for (int i = 0; i < 5; i++) {
for (Member m : members) {
// warm up cpu for iteration
}
members.forEach(Member::getID);
}
}
private static void testSolutions() {
long start = System.nanoTime();
int result1 = getNextID();
System.out.println("#1 Iterative result: " + result1 + " | in " + (System.nanoTime() - start) / 1000000.0 + "ms");
start = System.nanoTime();
Member m = members.stream().filter(member -> member.getID() != members.indexOf(member)).findFirst().orElse(null);
int result2 = m != null ? members.indexOf(m) : members.size();
System.out.println("#2 Stream Result: " + result2 + " | in " + ((System.nanoTime() - start) / 1000000.0) + "ms");
start = System.nanoTime();
int result3 = members.stream().filter(member -> member.getID() != members.indexOf(member)).findFirst().map(m2 -> members.indexOf(m2)).orElse(members.size());
System.out.println("#3 Stream Result: " + result3 + " | in " + ((System.nanoTime() - start) / 1000000.0) + "ms");
}
private static int getNextID() {
for (int i = 0; i < members.size(); i++) {
if (i < members.get(i).getID()) {
return i;
}
}
return members.size();
}
private static List<Member> getTestList(int count) {
List<Member> members = new ArrayList<>();
for (int i = 0; i < count; i++) {
members.add(new Member(i));
}
return members;
}
private static class Member {
private int id;
public Member(int id) {
this.id = id;
}
private int getID() {
return id;
}
}
}