Размеры динамических массивов Java?

У меня есть класс - xClass, который я хочу загрузить в массив xClass, поэтому я объявляю:

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

Однако я не знаю, понадобится ли мне 10. Мне может понадобиться 8 или 12 или любой другой номер. Я не буду знать до времени исполнения. Могу ли я изменить количество элементов в массиве "на лету"? Если да, то как?

Ответ 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> mysclass = 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); }
}

Ответ 2

В длину массива java исправлена.

Вы можете использовать Список для хранения значений и при необходимости использовать метод 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 создается с нулевыми элементами. Вы не можете просто создать ArrayList с 20 элементами, а затем вызвать set(15, foo).
  • Вы не можете напрямую изменить размер ArrayList. Вы делаете это косвенно, используя различные методы add, insert и remove.

Если вам нужно что-то большее, подобное массиву, вам нужно будет создать свой собственный API. (Может быть, кто-то может прослушивать существующую стороннюю библиотеку... Я не мог найти один с 2-минутным "исследованием" с помощью Google:-))

Если вам действительно нужен массив, который растет, когда вы его инициализируете, то это что-то вроде этого.

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

Да, оберните его и используйте структуру Collections.

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

Затем используйте List.toArray(), если это необходимо, или просто перечислите указанный список.

Ответ 7

Как говорят другие пользователи, вам, вероятно, нужна реализация java.util.List.

Если по какой-то причине вам понадобится массив, вы можете сделать две вещи:

  • Используйте список, а затем преобразуйте его в массив с myList.toArray()

  • Используйте массив определенного размера. Если вам нужен более или менее размер, вы можете изменить его с помощью методов java.util.Arrays.

Лучшее решение будет зависеть от вашей проблемы;)

Ответ 8

Вместо этого я рекомендую использовать векторы. Очень прост в использовании и имеет множество предопределенных методов для реализации.

import java.util.*;

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

для добавления элемента просто используйте:

v.addElement(int);

В (5,2) первый 5 является начальным размером вектора. Если вы превысите начальный размер, вектор будет расти на 2 места. Если он снова превысит его, он снова увеличится на 2 места и т.д.

Ответ 9

Arrays.copyOf() метод имеет множество возможностей для исправления проблемы с увеличением длины массива.

Java API

Ответ 10

Если вы объявляете массив myclass [] следующим образом:

xClass myclass[] = new xClass[10]

просто передайте в качестве аргумента количество элементов XClass, которые вам понадобятся. В этот момент вы знаете, сколько вам понадобится? Объявив массив как имеющий 10 элементов, вы не объявляете 10 объектов XClass, вы просто создаете массив с 10 элементами типа xClass.

Ответ 11

Хорошая практика - получить сумму, которую нужно сохранить сначала, а затем инициализировать массив.

Например, вы должны спросить пользователя, сколько данных ему нужно сохранить, а затем инициализировать, или запросить компонент или аргумент о том, сколько вам нужно хранить. если вы хотите использовать динамический массив, вы можете использовать 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 может содержать объекты, в отличие от других примитивных типов данных, и их очень легко манипулировать, а удаление чего-либо из середины также легко, полностью динамическое. С помощью List и Stack

Ответ 12

Размеры массива Java фиксированы, вы не можете создавать динамические массивы, как в С++.

Ответ 13

Я не знаю, можете ли вы изменить размер во время выполнения, но вы можете выделить размер во время выполнения. Попробуйте использовать этот код:

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.

Ответ 14

Здесь используется метод, который не использует 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);
        }
    }

Ответ 15

В массивах массивов 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 с содержимым исходного массива ie. STCK []. А затем снова скопируйте его обратно в исходное, предоставив нам новый массив новых SIZE.

Несомненно, он генерирует CPU Overhead из-за повторной инициализации массива с использованием цикла while. Но вы все равно можете использовать и реализовать его в своем коде. Для лучшей практики используйте "Связанный список" вместо Array, если вы хотите, чтобы данные хранились динамически в памяти переменной длины.

Здесь пример реального времени, основанный на динамических стеках, чтобы увеличить размер массива во время выполнения

Имя файла: 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);

}

}

Надеюсь, что это решает ваш запрос.

Ответ 16

Да, мы можем сделать это.

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


}

Ответ 17

Так как 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.