2009-10-30 18 views
78

tengo una clase - xClass, que yo quiero cargar en una matriz de xClass por lo que la declaración:¿Tamaños de matriz dinámicos de Java?

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

Sin embargo, no sé si necesitaré 10. Es posible que necesite 8 o 12 o cualquier otro número para ese asunto. No lo sabré hasta el tiempo de ejecución. ¿Puedo cambiar el número de elementos en una matriz sobre la marcha? Si es así, ¿cómo?

+0

me fijo hasta el formato de la pregunta, puede simplemente el título si lo desea, simplemente ser descriptivo. y bienvenidos a stackoverflow! : D –

Respuesta

128

No, no puede cambiar el tamaño de una matriz una vez creada. O tiene que asignarlo más grande de lo que cree que necesitará o aceptar la sobrecarga de tener que reasignarlo para crecer. Cuando lo hace tendrá que asignar uno nuevo y copiar los datos de la antigua a la nueva:

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; 

Si usted se encuentra en esta situación, me gustaría recomendar encarecidamente el uso de las colecciones de Java en su lugar. En particular ArrayList envuelve esencialmente una matriz y se encarga de la lógica para el cultivo de la matriz como sea necesario:

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

Generalmente un ArrayList es una solución preferible a una matriz de todos modos por varias razones. Por un lado, las matrices son mutables. Si usted tiene una clase que hace esto:

class Myclass { 
    private int items[]; 

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

que haya creado un problema, ya que una persona que llama puede cambiar su miembro de datos privados, lo que conduce a todo tipo de copia defensiva. Compare esto con la versión de lista:

class Myclass { 
    private List<Integer> items; 

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

Uso ArrayList en lugar de List y todo funciona bien. – ConductedClever

6

se ajusta el número de elementos a cualquier cosa que desee en el momento de crearlo:

xClass[] mysclass = new xClass[n]; 

A continuación, puede inicializar los elementos en un bucle. Supongo que esto es lo que necesitas.

Si necesita agregar o quitar elementos a la matriz después de crearla, entonces deberá usar un ArrayList.

1

Cuando se declara la [] array miclase como:

xClass myclass[] = new xClass[10] 

, simplemente pasan como argumento el número de elementos XClass que necesitará. En ese momento, ¿sabes cuántos necesitarás? Al declarar que el conjunto tiene 10 elementos, no declaras 10 objetos XClass, solo estás creando un conjunto con 10 elementos de tipo xClass.

2

Sí, envuélvala y use el marco de Colecciones.

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

A continuación, utilice List.toArray() cuando sea necesario, o simplemente itere sobre dicha lista.

7

Como han dicho otros, no puede cambiar el tamaño de una matriz de Java existente.

ArrayList es lo más parecido que tiene Java estándar a una matriz de tamaño dinámico. Sin embargo, hay algunas cosas sobre ArrayList (en realidad, la interfaz de la Lista) que no son "tipo array". Por ejemplo:

  • No puede usar [ ... ] para indexar una lista.Tienes que usar los métodos get(int) y set(int, E).
  • Una ArrayList se crea con cero elementos. No se puede crear un ArrayList con 20 elementos y luego llamar al set(15, foo).
  • No puede cambiar directamente el tamaño de una ArrayList. Lo haces indirectamente usando los diversos métodos add, insert y remove.

Si quiere algo más parecido a una matriz, tendrá que diseñar su propia API. (Tal vez alguien podría hablar con una biblioteca de terceros existente ... No pude encontrar uno con 2 minutos de "investigación" con Google :-))

Si realmente solo necesitas una matriz que crezca tal como eres Inicializándolo, entonces la solución es algo como esto.

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()]); 
20

En java la longitud de la matriz es fija.

Usted puede utilizar una lista para contener los valores e invocar el método toArray si es necesario Véase el siguiente ejemplo:

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 {} 
2

Como dicen otros usuarios, es probable que tenga una implementación de java.util.List.

Si, por alguna razón, que finalmente necesita una matriz, puede hacer dos cosas:

  • utilizar una lista y luego convertirlo en una matriz con myList.toArray()

  • Use una matriz de cierto tamaño. Si necesita más o menos tamaño, puede modificarlo con los métodos java.util.Arrays.

mejor solución dependerá de su problema;)

2

recomiendo el uso de vectores lugar. Muy fácil de usar y tiene muchos métodos predefinidos para la implementación.

import java.util.*; 

Vector<Integer> v=new Vector<Integer>(5,2); 

para añadir un elemento utilizar simplemente:

v.addElement(int); 

En el (5,2) la primera 5 es el tamaño inicial del vector. Si excede el tamaño inicial, el vector crecerá en 2 lugares. Si excede nuevamente, aumentará nuevamente en 2 lugares y así sucesivamente.

+4

A menos que necesite específicamente un tipo seguro para subprocesos (-ish), debe usar ArrayList en lugar de Vector. –

2

Arrays.copyOf() método tiene muchas opciones para solucionar el problema con la longitud de la matriz aumentando dinámicamente.

Java API

+0

Para ser específico: if (i> = mysclass.length) mysclass = Arrays.copyOf (mysclass, i + 1); mysclass [i] = new MyClass(); –

4

Puede utilizar 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()); 
0

Es una buena práctica obtener la cantidad que necesita para almacenar primero y luego inicializar la matriz.

por ejemplo, le preguntaría al usuario cuántos datos necesita almacenar y luego inicializarlos, o consultar el componente o argumento de cuántos necesita almacenar. si desea una matriz dinámica, puede usar ArrayList() y usar la función al.add(); para seguir agregando, luego puede transferirla a una matriz fija.

//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); 
} 

lo hace, es redundante, pero sólo para mostrar la idea, ArrayList puede contener objetos a diferencia de otros tipos de datos simples y son muy fáciles de manipular, la eliminación de cualquier cosa, desde el centro es fácil, así, por completo con dynamic.same List y Stack

0

Los tamaños de matriz de Java son fijos, no se pueden hacer arreglos dinámicos como los de en C++.

0

No sé si puede cambiar el tamaño en tiempo de ejecución, pero puede asignar el tamaño en tiempo de ejecución. Intente utilizar este código:

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]; 
    } 
} 

esto asigna su tamaño de matriz para ser el ingresado en tiempo de ejecución en x.

0

Aquí hay un método que no utiliza ArrayList. El usuario especifica el tamaño y puede agregar un ciclo do-while para la recursión.

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); 
     } 
    } 
0

En tamaños de los arreglos en Java son siempre de longitud fija pero no hay forma en que puede el más aumenta dinámicamente el tamaño de la matriz en tiempo de ejecución sí mismo

Ésta es "utilizado", así como manera de hacer IT

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

En el código anterior estamos inicializando a [] array nuevo temp, y usando adicionalmente un bucle para inicializar el contenido de la temp con el contenido de la matriz original es decir preferido. stck []. Y luego volviendo a copiarlo al original, dándonos una nueva variedad de TAMAÑO nuevo.

Sin duda, genera una sobrecarga de la CPU debido a la reinicialización de una matriz utilizando for loop repetidamente. Pero aún puede usarlo e implementarlo en su código. Para la mejor práctica, use "Lista enlazada" en lugar de Array, si desea que los datos se almacenen dinámicamente en la memoria, de longitud variable.

Aquí hay un ejemplo en tiempo real basado en dinámicas Pilas para aumentar el tamaño del orden de batalla en tiempo de ejecución

de nombre de archivo: 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(); 
} 

} 

de nombre de archivo: Exec.java
(con la clase principal)

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); 

} 

} 

Espero que haya solucionado tu duda.

0

Sí, podemos hacerlo de esta manera.

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]); 
     } 
    } 


} 
0

Dado que ArrayList lleva a la cantidad de memoria cuando necesito variedad de tipos primitivos, yo prefiero usar IntStream.builder() para crear int matriz (También puede utilizar constructores LongStream y DoubleStream).

Ejemplo:

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

Nota: disponible a partir de Java 8.