【问题标题】:Java dynamic array sizes?Java动态数组大小?
【发布时间】:2010-12-11 11:03:54
【问题描述】:

我有一个类 - xClass,我想将它加载到 xClass 数组中,所以我声明:

xClass mysclass[] = new xClass[10];
myclass[0] = new xClass();
myclass[9] = new xClass();

但是,我不知道我是否需要 10。我可能需要 8 或 12 或任何其他数字。直到运行时我才知道。 我可以即时更改数组中的元素数量吗? 如果有,怎么做?

【问题讨论】:

  • 我修正了问题的格式,如果你愿意,你可以只是标题,只是描述性的。欢迎来到stackoverflow! :D

标签: java


【解决方案1】:

不,一旦创建数组,您就无法更改其大小。您要么必须分配比您认为需要的更大的空间,要么接受必须重新分配它的开销以增加大小。当它发生时,您必须分配一个新数据并将数据从旧数据复制到新数据:

int[] oldItems = new int[10];
for (int i = 0; i < 10; i++) {
    oldItems[i] = i + 10;
}
int[] newItems = new int[20];
System.arraycopy(oldItems, 0, newItems, 0, 10);
oldItems = newItems;

如果您发现自己处于这种情况,我强烈建议您改用 Java 集合。特别是 ArrayList 本质上包装了一个数组,并根据需要处理增长数组的逻辑:

List<XClass> myclass = new ArrayList<XClass>();
myclass.add(new XClass());
myclass.add(new XClass());

出于多种原因,通常ArrayList 是数组的首选解决方案。一方面,数组是可变的。如果您有这样的课程:

class Myclass {
    private int[] items;

    public int[] getItems() {
        return items;
    }
}

您已经制造了一个问题,因为调用者可以更改您的私有数据成员,这会导致各种防御性复制。将此与列表版本进行比较:

class Myclass {
    private List<Integer> items;

    public List<Integer> getItems() {
        return Collections.unmodifiableList(items);
    }
}

【讨论】:

  • List 是接口,ArrayList 是实现。将其创建为 ArrayList 但将其称为 List(以便以后可以更改)是正确的。
【解决方案2】:

在java中数组长度是固定的。

您可以使用 List 来保存值并在需要时调用 toArray 方法 请参阅以下示例:

import java.util.List;
import java.util.ArrayList;
import java.util.Random;

public class A  {

    public static void main( String [] args ) {
        // dynamically hold the instances
        List<xClass> list = new ArrayList<xClass>();

        // fill it with a random number between 0 and 100
        int elements = new Random().nextInt(100);  
        for( int i = 0 ; i < elements ; i++ ) {
            list.add( new xClass() );
        }

        // convert it to array
        xClass [] array = list.toArray( new xClass[ list.size() ] );


        System.out.println( "size of array = " + array.length );
    }
}
class xClass {}

【讨论】:

    【解决方案3】:

    正如其他人所说,您无法更改现有 Java 数组的大小。

    ArrayList 是标准 Java 中最接近动态大小的数组。但是,ArrayList(实际上是 List 接口)有些东西不是“像数组一样”。例如:

    • 您不能使用[ ... ] 来索引列表。您必须使用get(int)set(int, E) 方法。
    • ArrayList 是用零个元素创建的。您不能简单地创建一个包含 20 个元素的 ArrayList,然后调用 set(15, foo)
    • 您不能直接更改 ArrayList 的大小。您可以使用各种 addinsertremove 方法间接完成。

    如果您想要更像数组的东西,您需要设计自己的 API。 (也许有人可以加入现有的第三方图书馆……我找不到一个用 Google 进行 2 分钟“研究”的图书馆 :-))

    如果您真的只需要一个在初始化时增长的数组,那么解决方案就是这样。

    ArrayList<T> tmp = new ArrayList<T>();
    while (...) {
        tmp.add(new T(...));
    }
    // This creates a new array and copies the element of 'tmp' to it.
    T[] array = tmp.toArray(new T[tmp.size()]);
    

    【讨论】:

      【解决方案4】:

      您可以在创建元素时将元素的数量设置为任何您想要的:

      xClass[] mysclass = new xClass[n];
      

      然后你可以循环初始化元素。我猜这就是你需要的。

      如果您需要在创建数组后添加或删除元素,则必须使用ArrayList

      【讨论】:

        【解决方案5】:

        你可以使用ArrayList:

        import java.util.ArrayList;
        import java.util.Iterator;
        

        ...

        ArrayList<String> arr = new ArrayList<String>();
        arr.add("neo");
        arr.add("morpheus");
        arr.add("trinity");
        Iterator<String> foreach = arr.iterator();
        while (foreach.hasNext()) System.out.println(foreach.next());
        

        【讨论】:

          【解决方案6】:

          正如其他用户所说,您可能需要 java.util.List 的实现。

          如果由于某种原因,你最终需要一个数组,你可以做两件事:

          • 使用 List,然后使用 myList.toArray() 将其转换为数组

          • 使用特定大小的数组。如果您需要更多或更少的大小,可以使用 java.util.Arrays 方法对其进行修改。

          最佳解决方案取决于您的问题;)

          【讨论】:

            【解决方案7】:

            Arrays.copyOf() 方法有很多选项可以解决数组长度动态增加的问题。

            Java API

            【讨论】:

            • 具体来说: if (i >= mysclass.length) mysclass= Arrays.copyOf(mysclass, i+1); mysclass[i] = new MyClass();
            【解决方案8】:

            是的,包装它并使用 Collections 框架。

            List l = new ArrayList();
            l.add(new xClass());
            // do stuff
            l.add(new xClass());
            

            然后在必要时使用 List.toArray(),或者只是迭代所述 List。

            【讨论】:

              【解决方案9】:

              我建议改用向量。非常易于使用,并且有许多预定义的实现方法。

              import java.util.*;
              
              Vector<Integer> v=new Vector<Integer>(5,2);
              

              添加元素只需使用:

              v.addElement(int);
              

              (5,2)中的前5个是向量的初始大小。如果超过初始大小,向量将增长 2 个位置。如果再次超过,则再次增加 2 位,以此类推。

              【讨论】:

              • 除非您特别需要线程安全 (-ish) 类型,否则您应该使用 ArrayList 而不是 Vector。
              【解决方案10】:

              将 myclass[] 数组声明为:

              xClass myclass[] = new xClass[10]
              

              ,只需将您需要的 XClass 元素的数量作为参数传入。那时你知道你需要多少吗?通过将数组声明为具有 10 个元素,您并不是在声明 10 个 XClass 对象,您只是在创建一个包含 10 个 xClass 类型元素的数组。

              【讨论】:

                【解决方案11】:

                Java 数组大小是固定的,不能像 C++ 那样制作动态数组。

                【讨论】:

                  【解决方案12】:

                  由于 ArrayList 在我需要原始类型数组时会占用大量内存,因此我更喜欢使用 IntStream.builder() 来创建 int 数组(您也可以使用 LongStream 和 DoubleStream 构建器)。

                  例子:

                  Builder builder = IntStream.builder();
                  int arraySize = new Random().nextInt();
                  for(int i = 0; i<arraySize; i++ ) {
                      builder.add(i);
                  }
                  int[] array = builder.build().toArray();
                  

                  注意:自 Java 8 起可用。

                  【讨论】:

                    【解决方案13】:

                    最好先获取需要存储的数量,然后再初始化数组。

                    例如,您会询问用户他需要存储多少数据然后对其进行初始化,或者查询您需要存储多少的组件或参数。 如果你想要一个动态数组你可以使用ArrayList()并使用al.add();函数继续添加,然后你可以将它转移到一个固定的数组。

                    //Initialize ArrayList and cast string so ArrayList accepts strings (or anything
                    ArrayList<string> al = new ArrayList(); 
                    //add a certain amount of data
                    for(int i=0;i<x;i++)
                    {
                      al.add("data "+i); 
                    }
                    
                    //get size of data inside
                    int size = al.size(); 
                    //initialize String array with the size you have
                    String strArray[] = new String[size]; 
                    //insert data from ArrayList to String array
                    for(int i=0;i<size;i++)
                    {
                      strArray[i] = al.get(i);
                    }
                    

                    这样做是多余的,但只是为了向您展示这个想法,ArrayList 可以保存与其他原始数据类型不同的对象并且非常容易操作,从中间删除任何东西也很容易,完全动态。与@987654325 相同@和Stack

                    【讨论】:

                      【解决方案14】:

                      我不知道您是否可以在运行时更改大小,但您可以在运行时分配大小。尝试使用此代码:

                      class MyClass {
                          void myFunction () {
                              Scanner s = new Scanner (System.in);
                              int myArray [];
                              int x;
                      
                              System.out.print ("Enter the size of the array: ");
                              x = s.nextInt();
                      
                              myArray = new int[x];
                          }
                      }
                      

                      这会将您的数组大小指定为在运行时输入到 x 中的大小。

                      【讨论】:

                        【解决方案15】:

                        这是一个不使用 ArrayList 的方法。用户指定大小,您可以添加一个 do-while 循环进行递归。

                        import java.util.Scanner;
                            public class Dynamic {
                                public static Scanner value;
                                public static void main(String[]args){
                                    value=new Scanner(System.in);
                                    System.out.println("Enter the number of tests to calculate average\n");
                                    int limit=value.nextInt();
                                    int index=0;
                                    int [] marks=new int[limit];
                                    float sum,ave;
                                    sum=0;      
                                    while(index<limit)
                                    {
                                        int test=index+1;
                                        System.out.println("Enter the marks on test " +test);
                                        marks[index]=value.nextInt();
                                        sum+=marks[index];
                                        index++;
                                    }
                                    ave=sum/limit;
                                    System.out.println("The average is: " + ave);
                                }
                            }
                        

                        【讨论】:

                          【解决方案16】:

                          在 Java 中,数组大小始终是固定长度的,但是有一种方法可以在运行时动态增加数组的大小

                          这是最“常用”也是首选的方式-

                              int temp[]=new int[stck.length+1];
                              for(int i=0;i<stck.length;i++)temp[i]=stck[i];
                              stck=temp;
                          

                          在上面的代码中,我们正在初始化一个新的 temp[] 数组,并进一步使用 for 循环将 temp 的内容初始化为原始数组的内容,即。 stck[]。然后再次将它复制回原来的那个,给我们一个新的 SIZE 数组。

                          毫无疑问,由于反复使用 for 循环重新初始化数组,它会产生 CPU 开销。但是您仍然可以在代码中使用和实现它。 对于最佳实践,如果您希望数据动态存储在可变长度的内存中,请使用“链接列表”而不是数组。

                          这是一个基于动态堆栈在运行时增加数组大小的实时示例

                          文件名:DStack.java

                          public class DStack {
                          private int stck[];
                          int tos;
                          
                          void Init_Stck(int size) {
                              stck=new int[size];
                              tos=-1;
                          }
                          int Change_Stck(int size){
                              return stck[size];
                          }
                          
                          public void push(int item){
                              if(tos==stck.length-1){
                                  int temp[]=new int[stck.length+1];
                                  for(int i=0;i<stck.length;i++)temp[i]=stck[i];
                                  stck=temp;
                                  stck[++tos]=item;
                              }
                              else
                                  stck[++tos]=item;
                          }
                          public int pop(){
                              if(tos<0){
                                  System.out.println("Stack Underflow");
                                  return 0;
                              }
                              else return stck[tos--];
                          }
                          
                          public void display(){
                              for(int x=0;x<stck.length;x++){
                                  System.out.print(stck[x]+" ");
                              }
                              System.out.println();
                          }
                          
                          }
                          

                          文件名:Exec.java
                          (与主类)

                          import java.util.*;
                          public class Exec {
                          
                          private static Scanner in;
                          
                          public static void main(String[] args) {
                              in = new Scanner(System.in);
                              int option,item,i=1;
                              DStack obj=new DStack();
                              obj.Init_Stck(1);
                              do{
                                  System.out.println();
                                  System.out.println("--MENU--");
                                  System.out.println("1. Push a Value in The Stack");
                                  System.out.println("2. Pop a Value from the Stack");
                                  System.out.println("3. Display Stack");
                                  System.out.println("4. Exit");
                                  option=in.nextInt();
                                  switch(option){
                                  case 1:
                                      System.out.println("Enter the Value to be Pushed");
                                      item=in.nextInt();
                                      obj.push(item);
                                      break;
                                  case 2:
                                      System.out.println("Popped Item: "+obj.pop());
                                      obj.Change_Stck(obj.tos);
                                      break;
                                  case 3:
                                      System.out.println("Displaying...");
                                      obj.display();
                                      break;
                                  case 4:
                                      System.out.println("Exiting...");
                                      i=0;
                                      break;
                                  default:
                                      System.out.println("Enter a Valid Value");
                          
                                  }
                              }while(i==1);
                          
                          }
                          
                          }
                          

                          希望这能解决您的问题。

                          【讨论】:

                            【解决方案17】:

                            是的,我们可以这样做。

                            import java.util.Scanner;
                            
                            public class Collection_Basic {
                            
                                private static Scanner sc;
                            
                                public static void main(String[] args) {
                            
                                    Object[] obj=new Object[4];
                                    sc = new Scanner(System.in);
                            
                            
                                    //Storing element
                                    System.out.println("enter your element");
                                    for(int i=0;i<4;i++){
                                        obj[i]=sc.nextInt();
                                    }
                            
                                    /*
                                     * here, size reaches with its maximum capacity so u can not store more element,
                                     * 
                                     * for storing more element we have to create new array Object with required size
                                     */
                            
                                    Object[] tempObj=new Object[10];
                            
                                    //copying old array to new Array
                            
                                    int oldArraySize=obj.length;
                                    int i=0;
                                    for(;i<oldArraySize;i++){
                            
                                        tempObj[i]=obj[i];
                                    }
                            
                                    /*
                                     * storing new element to the end of new Array objebt
                                     */
                                    tempObj[i]=90;
                            
                                    //assigning new array Object refeence to the old one
                            
                                    obj=tempObj;
                            
                                    for(int j=0;j<obj.length;j++){
                                        System.out.println("obj["+j+"] -"+obj[j]);
                                    }
                                }
                            
                            
                            }
                            

                            【讨论】:

                              【解决方案18】:

                              你可以做一些事情

                              private  static Person []  addPersons(Person[] persons, Person personToAdd) {
                                  int currentLenght = persons.length;
                              
                                  Person [] personsArrayNew = Arrays.copyOf(persons, currentLenght +1);
                                  personsArrayNew[currentLenght]  = personToAdd;
                              
                                  return personsArrayNew;
                              
                              }
                              

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 2014-07-21
                                • 2011-05-03
                                • 2019-02-10
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2011-10-24
                                相关资源
                                最近更新 更多