Размеры динамических массивов 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.