Java 我们如何动态分配和增长阵列

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

我正在从事一个项目,但我不能使用任何现有的java数据结构(即ArraysList、trees等)

我只能使用数组。因此,我需要使用新内存动态更新数组

我从一个文本文件中读取,我为数组内存预分配了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多个项目的文本文件,我就会得到一个分配错误

我如何动态更新这个数组(从而重新发明轮子)

谢谢

分配一个新数组(例如,容量加倍),并将所有元素移动到该数组中

基本上,您需要检查
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]);
    }

}