我正在开发一个项目,但我不能使用任何现有的java数据结构(即ArraysList,树等)
我只能使用数组。因此,我需要使用新内存动态更新数组。
我正在读取文本文件,并为阵列内存预先分配100:
String [] wordList;
int wordCount = 0;
int occurrence = 1;
int arraySize = 100;
wordList = new String[arraySize];
while ((strLine = br.readLine()) != null) {
// Store the content into an array
Scanner s = new Scanner(strLine);
while(s.hasNext()) {
wordList[wordCount] = s.next();
wordCount++;
}
}
现在这适用于100个以下列表项。 br.readline是遍历文本文件每一行的缓冲读取器。我有它然后将每个单词存储到列表中,然后递增我的索引(wordCount)。
但是,一旦我的文本文件超过100个,我就会收到分配错误。
如何动态更新此阵列(从而重新发明轮子)?
谢谢!
答案 0 :(得分:18)
您可以这样做:
String [] wordList;
int wordCount = 0;
int occurrence = 1;
int arraySize = 100;
int arrayGrowth = 50;
wordList = new String[arraySize];
while ((strLine = br.readLine()) != null) {
// Store the content into an array
Scanner s = new Scanner(strLine);
while(s.hasNext()) {
if (wordList.length == wordCount) {
// expand list
wordList = Arrays.copyOf(wordList, wordList.length + arrayGrowth);
}
wordList[wordCount] = s.next();
wordCount++;
}
}
使用java.util.Arrays.copyOf(String[])
基本上做同样的事情:
if (wordList.length == wordCount) {
String[] temp = new String[wordList.length + arrayGrowth];
System.arraycopy(wordList, 0, temp, 0, wordList.length);
wordList = temp;
}
除了它是一行代码而不是三行。 :)
答案 1 :(得分:5)
您分配一个新数组(例如,容量加倍),并将所有元素移动到它。
基本上你需要检查wordCount
是否即将命中wordList.size()
,当它发生时,创建一个长度是前一个数组长度两倍的新数组,并将所有元素复制到它(创建一个辅助方法来执行此操作),并将wordList
分配给新阵列。
要复制内容,可以使用System.arraycopy
,但我不确定是否允许使用您的限制,因此您只需逐个复制元素:
public String[] createNewArray(String[] oldArray){
String[] newArray = new String[oldArray.length * 2];
for(int i = 0; i < oldArray.length; i++) {
newArray[i] = oldArray[i];
}
return newArray;
}
继续。
答案 2 :(得分:3)
看看Java ArrayList的实施情况。 Java ArrayList
在内部使用固定大小的数组,并在元素数量超过当前大小时重新分配数组。您也可以在类似的行上实现。
答案 3 :(得分:2)
您无法动态增加数组大小,因此您可以更好地复制到新的array
。使用System.arrayCopy
,比将每个元素复制到新数组更好。以供参考
Why is System.arraycopy native in Java?
private static Object resizeArray (Object oldArray, int newSize) {
int oldSize = java.lang.reflect.Array.getLength(oldArray);
Class elementType = oldArray.getClass().getComponentType();
Object newArray = java.lang.reflect.Array.newInstance(
elementType, newSize);
int preserveLength = Math.min(oldSize, newSize);
if (preserveLength > 0)
System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
return newArray;
}
答案 4 :(得分:0)
您必须手动创建一个新的更大的数组并复制这些项目。
this可能有所帮助
答案 5 :(得分:0)
Visual Basic有一个很好的功能:ReDim Preserve
。
有人写了一个等效函数 - 你可以找到它here。我认为它完全符合您的要求(而且您不是在重新发明轮子 - 您正在复制别人的......)
答案 6 :(得分:0)
让我们假设你有一个1个元素的数组,并且想要扩展大小以动态容纳100万个元素。
案例1:
String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 1];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
案例2(通过加法因子增加大小):
String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 10];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
案例3(乘以倍数增加大小):
String [] wordList = new String[1];
String [] tmp = new String[wordList.length * 2];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
当动态扩展数组的大小时,使用Array.copy或迭代数组并使用for循环将元素复制到新数组,实际上迭代数组的每个元素。这是一项昂贵的操作。 Array.copy将是干净和优化的,仍然很昂贵。所以,我建议用乘法因子增加数组长度。
它是如何帮助的,
在案例1中,要容纳100万个元素,你必须增加100万个数组的大小 - 1倍,即999,999次。
在第2种情况下,你必须增加数组的大小100万次/ 10次 - 1次,即99,999次。
在第3种情况下,你必须按log 2 100万 - 1次增加数组的大小,即18.9(假设)。
答案 7 :(得分:0)
public class Arr {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = {1,2,3};
//let a[] is your original array
System.out.println(a[0] + " " + a[1] + " " + a[2]);
int b[];
//let b[] is your temporary array with size greater than a[]
//I have took 5
b = new int[5];
//now assign all a[] values to b[]
for(int i = 0 ; i < a.length ; i ++)
b[i] = a[i];
//add next index values to b
b[3] = 4;
b[4] = 5;
//now assign b[] to a[]
a = b;
//now you can heck that size of an original array increased
System.out.println(a[0] + " " + a[1] + " " + a[2] + " " + a[3] + " "
+ a[4]);
}
}
上述代码的输出是:
1 2 3
1 2 3 4 5