给定空列表,然后添加String(ArrayList实现)



我正在尝试实现我自己的ArrayList。这是我迄今为止的代码:

public class StringArrayList {
private int size = 0;
private String[] strings = new String[0];
// Constructors
public StringArrayList(){
strings = new String[size];
};
public StringArrayList(int initialCapacity){
strings = new String[0];
}
public StringArrayList(String[] strings){
this.strings = strings;
size = strings.length;
}
public int size() {
return size;
}
public String get(int index){
return strings[index];
}
public boolean add(String content){
boolean add = false;
strings = new String[10];
for(int i = 0; i < strings.length; i++){
if(strings[i] == null) {
strings[i] = content;
return true;
}
}
return add;
}

我必须使以下测试成功:

public void add__given_empty_list__then_adds_string()
{
StringArrayList lst = list();
lst.add( "string" );
assertSameItems( list( "string" ), lst );
}

我得到这个错误:

java.lang.AssertionError: expected<1> but was <0>

事实上,我迷失在别人对我的要求中。我知道null和空列表之间有区别,但如果我不指定那么null,我会得到ArrayOutOfBounds异常。

我有什么不明白的。

谢谢

您的实现有一些错误。

public StringArrayList(int initialCapacity){
strings = new String[0];
}

这种类型的构造函数用于分配初始容量,而不是"0"。

最重要的是,add方法实际上并没有添加新元素,而是覆盖当前的内部数组,并将新元素放置在第0个索引处(不增加size变量)。

public boolean add(String content){
boolean add = false; //unnecessary, can replace bottom `add` with `false` for same result
strings = new String[10]; //overwrites internal array of "list" with a new array
for(int i = 0; i < strings.length; i++){
if(strings[i] == null) { //will always replace only first element as this is a new array
strings[i] = content;
return true;
}
}
return add;
}

size变量用于跟踪当前数组包含的元素数量(添加新元素时会增加)。

知道了这一点,您就可以在strings[size]中添加一个新元素来添加一个新元素,以防size < strings.length为真。

如果不满足该条件(您希望添加的容量超过当前容量),则应通过创建新阵列、将以前的所有元素复制到新阵列中、然后替换旧阵列以及将新元素添加到新阵列来"调整"内部阵列的大小。

编辑:您的新代码

public boolean add(String content) { 
strings = new String[strings.length+1]; //still erases the internal array!
strings[0] = content; //only modifies the first element, rather than add to the list
size = 1; //if it was implemented correctly, this would be size++;
return true; 
} 

进行一个向列表中添加两个元素的测试,并断言列表是否同时包含这两个元素。

第2版:

这里有一个应该有效的解决方案:

public class StringArrayList {
private int size = 0;
private String[] strings;
// Constructors
public StringArrayList() {
this(0);
};
public StringArrayList(int initialCapacity){
String[] innerStrings = new String[initialCapacity];
this(innerStrings);
}
public StringArrayList(String[] strings){
this.strings = strings;
}
public int size() {
return size;
}
public String get(int index){
return strings[index];
}
public boolean add(String content){
if(size == strings.length) {
String[] newStrings = new String[size+10];
for(int i = 0; i < size; i++) {
newStrings[i] = strings[i];
}
strings = newStrings;
}
strings[size++] = content;
return true;
}
}

第3版:

public boolean add(String content){ 
if(size == strings.length) { 
String[] temp_list = new String[strings.length]; //no need to allocate a new array here if this is just to store your current array
temp_list = strings; 
strings = new String[size++]; //wrong, this allocates a `size`-long array and increases `size` by 1 afterwards, rather than create a new, larger internal array
strings = temp_list; //this just overwrites your internal array with the old array which is not increased in size
} 
for(int i = 0; i < strings.length; i++) { 
if(strings[i] == null) { //this is not necessary with proper `size`
strings[i] = content; 
} 
} 
return true; 
}

您的add实现不正确

它将始终重写内部strings数组,并将传递的参数设置为第一个元素。

失败的原因是add(String)方法没有递增size变量

当前您正在使用if(strings[i] == null) {来确定应在何处添加新元素。但是arraylist可以包含null。。。

我认为数组的长度(例如arraylist的容量)和大小字段之间应该有区别。

size字段可能应该指示列表中当前有多少元素。当由于大小等于数组长度而无法添加新元素时,则需要进行一些工作来创建一个新的、更大的数组,并将所有元素从旧数组复制到新数组。

顺便说一句,我注意到你在构造函数中没有使用initialCapacity参数。这可能应该用于将数组初始化为该长度。

最新更新