私はクラス-xClassを持っています。これをxClassの配列にロードしたいので、宣言を行います。
xClass mysclass[] = new xClass[10];
myclass[0] = new xClass();
myclass[9] = new xClass();
ただし、10が必要かどうかはわかりません。そのためには、8か12、またはその他の数が必要になる場合があります。実行時までわかりません。配列の要素数をその場で変更できますか?もしそうなら、どうですか?
私はクラス-xClassを持っています。これをxClassの配列にロードしたいので、宣言を行います。
xClass mysclass[] = new xClass[10];
myclass[0] = new xClass();
myclass[9] = new xClass();
ただし、10が必要かどうかはわかりません。そのためには、8か12、またはその他の数が必要になる場合があります。実行時までわかりません。配列の要素数をその場で変更できますか?もしそうなら、どうですか?
回答:
いいえ、一度作成した配列のサイズを変更することはできません。必要以上に大きいサイズを割り当てるか、サイズを大きくするために再割り当てしなければならないオーバーヘッドを受け入れる必要があります。その場合、新しいものを割り当て、データを古いものから新しいものにコピーする必要があります。
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とにかく、いくつかの理由から、アレイは一般にアレイの望ましいソリューションです。1つには、配列は変更可能です。これを行うクラスがある場合:
class Myclass {
private int[] items;
public int[] getItems() {
return items;
}
}
呼び出し元がプライベートデータメンバーを変更できるため、あらゆる種類の防御コピーにつながる問題が発生しました。これをリストバージョンと比較します。
class Myclass {
private List<Integer> items;
public List<Integer> getItems() {
return Collections.unmodifiableList(items);
}
}
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 {}
他の人が言ったように、既存のJava配列のサイズを変更することはできません。
ArrayListは、標準のJavaが動的サイズの配列に最も近いものです。ただし、ArrayList(実際にはListインターフェース)には、「配列のように」ではないものがあります。例えば:
[ ... ]してリストのインデックスを作成することはできません。メソッドget(int)とset(int, E)メソッドを使用する必要があります。set(15, foo)。add、メソッドを使用して間接的にinsert行いremoveます。より配列のようなものが必要な場合は、独自の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()]);
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());
Arrays.copyOf() メソッドには、配列の長さが動的に増加する問題を修正するための多くのオプションがあります。
代わりにベクターを使用することをお勧めします。非常に使いやすく、実装のための多くの定義済みメソッドがあります。
import java.util.*;
Vector<Integer> v=new Vector<Integer>(5,2);
要素を追加するには、以下を使用します。
v.addElement(int);
(5,2)第5ベクトルの初期サイズです。初期サイズを超えると、ベクトルは2桁大きくなります。再び超えると、再び2桁増加します。
Java配列のサイズは固定です。C++の場合のように動的配列を作成することはできません。
最初に格納する必要がある量を取得してから、配列を初期化することをお勧めします。
たとえば、格納する必要のあるデータの数をユーザーに尋ね、それを初期化するか、格納する必要のある数のコンポーネントまたは引数をクエリします。動的配列が必要な場合は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と完全にdynamic.same、他のプリミティブデータ型とは異なり、オブジェクトを保持して操作することは非常に簡単ですが、途中から何かを削除すると、同様に簡単ですListし、Stack
実行時にサイズを変更できるかどうかはわかりませんが、実行時にサイズを割り当てることができます。このコードを使用してみてください:
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に入力された配列サイズが割り当てられます。
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);
}
}
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);
}
}
これでクエリが解決することを願っています。
はい、このようにできます。
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]);
}
}
}
プリミティブ型の配列が必要な場合、ArrayListは大量のメモリを使用するため、int配列の作成にはIntStream.builder()を使用することをお勧めします(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以降で使用可能です。