Java 我们如何动态分配和增长阵列
我正在从事一个项目,但我不能使用任何现有的java数据结构(即ArraysList、trees等) 我只能使用数组。因此,我需要使用新内存动态更新数组 我从一个文本文件中读取,我为数组内存预分配了100:Java 我们如何动态分配和增长阵列,java,arrays,word-count,Java,Arrays,Word Count,我正在从事一个项目,但我不能使用任何现有的java数据结构(即ArraysList、trees等) 我只能使用数组。因此,我需要使用新内存动态更新数组 我从一个文本文件中读取,我为数组内存预分配了100: String [] wordList; int wordCount = 0; int occurrence = 1; int arraySize = 100; wordList = new String[arraySize]; while ((strLine
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多个项目的文本文件,我就会得到一个分配错误
我如何动态更新这个数组(从而重新发明轮子)
谢谢 分配一个新数组(例如,容量加倍),并将所有元素移动到该数组中
基本上,您需要检查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;
}
public String[]createNewArray(String[]oldArray){
String[]newArray=新字符串[oldArray.length*2];
对于(int i=0;i
继续。您必须手动创建一个新的更大的数组,并在项目上进行复制
可能会有所帮助您无法在复制到新的
阵列
时更好地动态增加阵列大小。为此,使用System.arrayCopy
比将每个元素复制到新数组中要好。供参考
您可以这样做:
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;
}
但它是一行代码,而不是三行代码。:) Visual Basic有一个很好的功能:
ReDim Preserve
有人写了一个等价的函数——你可以找到它。我认为它完全符合您的要求(而且您不是在重新发明轮子-您是在复制其他人的轮子)。看看它的实现。Java
ArrayList
在内部使用固定大小的数组,并在元素数量超过当前大小时重新分配数组。您也可以在类似的线路上实现 让我们举一个例子,当您有一个由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;
String[]wordList=新字符串[1];
String[]tmp=新字符串[wordList.length+1];
for(int i=0;i
情况2(通过增加系数增加尺寸):
String[]wordList=新字符串[1];
字符串[]tmp=新字符串[wordList.length+10];
for(int i=0;i
情况3(通过乘法因子增加尺寸):
String[]wordList=新字符串[1];
字符串[]tmp=新字符串[wordList.length*2];
for(int i=0;i
当使用Array.copy动态扩展数组的大小或迭代数组并使用for循环将元素复制到新数组时,实际上迭代数组的每个元素。这是一项耗资巨大的行动。Array.copy将是干净和优化的,但成本仍然很高。因此,我建议将数组长度增加一个乘法因子
它的帮助是
在案例1中,要容纳100万个元素,必须将阵列大小增加100万-1倍,即999999倍
在案例2中,您必须将阵列的大小增加100万/10-1倍,即99999倍
在案例3中,您必须将数组的大小增加log2100万-1倍,即18.9(假设)。公共类Arr{
公共静态void main(字符串[]args){
//TODO自动生成的方法存根
int a[]={1,2,3};
//设[]为原始数组
System.out.println(a[0]+“”+a[1]+“”+a[2]);
int b[];
//设b[]为临时数组,其大小大于a[]
//我已经吃了5片了
b=新整数[5];
//现在将所有a[]值分配给b[]
for(int i=0;i
上述代码的输出为:
1 2 3
1 2 3 4 5我认为最快的解决方案是计算输入文件中的行数(
wc-l filename
in'nix),并首次将数组分配到正确的大小。所有这些复制都比将文件倒回并读取两次要慢得多…也可能是重复的,请参阅:或者您可以使用array=Arrays.copyOf(array,newLength)
。是的,我知道。就像我说的,这个建议是在他不能使用内置方法的情况下提出的。。。同样,他不能使用ArrayList等。或者你可以只使用array=Arrays.copyOf(array,newLength)
。当然。。。如果你认为重新执行一个标准的库方法是“相同的”。@布莱恩罗奇,我希望你检查了图书馆的实施,你是什么意思?你能说得具体一点吗?就是这样。你重新发明了轮子(不必要),并使它成为需要显式转换的工具。我并不是说它没有显示OP如何工作的价值,只是正确的答案是使用标准库(和
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;
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;
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;
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]);
}
}