जावा गतिशील सरणी आकार?


106

मेरे पास एक वर्ग है - xClass, कि मैं xClass की एक सरणी में लोड करना चाहता हूं, इसलिए मैं घोषणा करता हूं:

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

हालाँकि, मुझे नहीं पता कि मुझे 10 की आवश्यकता होगी। मुझे उस मामले के लिए 8 या 12 या किसी अन्य संख्या की आवश्यकता हो सकती है। मुझे रनटाइम तक पता नहीं चलेगा। क्या मैं मक्खी पर किसी सरणी में तत्वों की संख्या बदल सकता हूं? यदि हां, तो कैसे?


मैंने प्रश्न का प्रारूपण तय किया, आप चाहें तो सिर्फ शीर्षक दे सकते हैं, केवल वर्णनात्मक हो सकते हैं। और stackoverflow में आपका स्वागत है! : डी
गॉर्डन गुस्ताफसन

जवाबों:


164

नहीं, आप एक बार बनाए गए सरणी का आकार नहीं बदल सकते। आपको या तो इसे अपने से बड़ा आवंटित करना होगा, जितना आपको लगता है कि आपको इसकी आवश्यकता होगी या इसके आकार में बढ़ने के लिए इसे पुनः प्राप्त करने के ओवरहेड को स्वीकार करना होगा। जब यह हो जाए तो आपको एक नया आवंटन करना होगा और पुराने से नए डेटा की प्रतिलिपि बनाना होगा:

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;

यदि आप इस स्थिति में खुद को पाते हैं, तो मैं इसके बजाय जावा कलेक्शंस का उपयोग करने की अत्यधिक सलाह दूंगा। विशेष रूप से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);
    }
}

1
सूची इंटरफ़ेस है और ArrayList कार्यान्वयन है। इसे एक ArrayList के रूप में बनाना लेकिन इसे एक List के रूप में संदर्भित करना (ताकि बाद में इसे बदल सकें) सही है।
CBGraham

26

जावा में सरणी की लंबाई निर्धारित है।

आप मानों को रखने के लिए सूची का उपयोग कर सकते हैं और 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 {}

8

जैसा कि अन्य लोगों ने कहा है, आप मौजूदा जावा सरणी के आकार को नहीं बदल सकते।

ArrayList निकटतम है जो मानक जावा में एक गतिशील आकार की सरणी है। हालाँकि, ArrayList (वास्तव में सूची इंटरफ़ेस) के बारे में कुछ चीजें हैं जो "सरणी की तरह" नहीं हैं। उदाहरण के लिए:

  • आप [ ... ]किसी सूची को अनुक्रमित करने के लिए उपयोग नहीं कर सकते । आपको get(int)और set(int, E)विधियों का उपयोग करना होगा ।
  • एक ArrayList शून्य तत्वों के साथ बनाया गया है। आप 20 तत्वों के साथ एक ArrayList बना सकते हैं और फिर कॉल नहीं कर सकते set(15, foo)
  • आप सीधे ArrayList का आकार नहीं बदल सकते। आप इसे अप्रत्यक्ष रूप से विभिन्न add, insertऔर removeविधियों का उपयोग करते हैं ।

यदि आप कुछ और तरह की सरणी चाहते हैं, तो आपको अपना एपीआई डिजाइन करना होगा। (हो सकता है कि कोई व्यक्ति किसी मौजूदा थर्ड पार्टी लाइब्रेरी के साथ झंकार कर सकता है ... मैं 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()]);

7

आप अपने द्वारा बनाए जाने वाले समय में अपने इच्छित तत्वों की संख्या निर्धारित करते हैं:

xClass[] mysclass = new xClass[n];

फिर आप तत्वों को एक लूप में शुरू कर सकते हैं। मैं अनुमान लगा रहा हूं कि यह वही है जो आपको चाहिए।

यदि आपको इसे बनाने के बाद सरणी में तत्वों को जोड़ना या निकालना है, तो आपको एक का उपयोग करना होगा ArrayList


6

आप 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());

3

Arrays.copyOf() एरे की लंबाई को गतिशील रूप से बढ़ाने के साथ विधि को ठीक करने के लिए कई विकल्प हैं।

जावा एपीआई


विशिष्ट होने के लिए: यदि (i> = mysclass.length) mysclass = Arrays.copyOf (mysclass, i + 1); mysclass [i] = new MyClass ();
माईच बर्जर

2

हां, इसे लपेटें और संग्रह ढांचे का उपयोग करें।

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

फिर जब आवश्यक हो, List.toArray () का उपयोग करें या उक्त सूची पर पुनरावृत्त करें।


2

जैसा कि अन्य उपयोगकर्ता कहते हैं, आपको शायद java.util.ist के कार्यान्वयन की आवश्यकता है।

यदि, किसी कारण से, आपको अंततः एक सरणी की आवश्यकता है, तो आप दो काम कर सकते हैं:

  • एक सूची का उपयोग करें और फिर इसे myList.toArray () के साथ एक सरणी में बदलें

  • निश्चित आकार के एक सरणी का उपयोग करें। यदि आपको अधिक या कम आकार की आवश्यकता है, तो आप इसे java.util.rrays विधियों से संशोधित कर सकते हैं।

सबसे अच्छा समाधान आपकी समस्या पर निर्भर करेगा;)


2

मैं इसके बजाय वैक्टर का उपयोग करने की सलाह देता हूं। उपयोग करने में बहुत आसान और कार्यान्वयन के लिए कई पूर्वनिर्धारित तरीके हैं।

import java.util.*;

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

एक तत्व जोड़ने के लिए बस का उपयोग करें:

v.addElement(int);

में (5,2) पहले 5 वेक्टर के प्रारंभिक आकार है। यदि आप प्रारंभिक आकार को पार करते हैं, तो वेक्टर 2 स्थानों से बढ़ेगा। यदि यह फिर से बढ़ जाता है, तो यह फिर से 2 स्थानों और बढ़ जाएगा।


4
जब तक आपको विशेष रूप से थ्रेड-सुरक्षित (-ish) प्रकार की आवश्यकता नहीं होती है, आपको वेक्टर के बजाय ArrayList का उपयोग करना चाहिए।
स्टीफन सी

1

जहाँ आप myclass घोषित करते हैं:

xClass myclass[] = new xClass[10]

, बस एक तर्क के रूप में आप की आवश्यकता होगी XClass तत्वों की संख्या के रूप में गुजरती हैं। उस बिंदु पर क्या आप जानते हैं कि आपको कितने की आवश्यकता होगी? सरणी को 10 तत्व के रूप में घोषित करके, आप 10 एक्सक्लास ऑब्जेक्ट घोषित नहीं कर रहे हैं, आप केवल टाइप एक्सक्लास के 10 तत्वों के साथ एक सरणी बना रहे हैं।


1

जावा सरणी आकार तय हो गए हैं, आप C + के रूप में डायनामिक एरे नहीं बना सकते हैं।


0

यह एक अच्छा अभ्यास है जो राशि आपको पहले स्टोर करने की आवश्यकता है फिर सरणी को इनिशियलाइज़ करें।

उदाहरण के लिए, आप उपयोगकर्ता से पूछेंगे कि उसे कितने डेटा को संग्रहीत करने और फिर उसे इनिशियलाइज़ करने की आवश्यकता है, या कितने स्टोर करने की आवश्यकता है, के घटक या तर्क को क्वेरी करें। यदि आप एक डायनामिक ऐरे चाहते हैं जिसे आप जोड़कर रखने के 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


0

मुझे नहीं पता कि आप रनटाइम पर आकार बदल सकते हैं लेकिन आप रनटाइम पर आकार आवंटित कर सकते हैं। इस कोड का उपयोग करने का प्रयास करें:

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 में रन टाइम में प्रवेश करने वाला बताता है।


0

यहाँ एक तरीका है जो ArrayList का उपयोग नहीं करता है। उपयोगकर्ता आकार निर्दिष्ट करता है और आप पुनरावृत्ति के लिए do-time लूप जोड़ सकते हैं।

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

जावा एरे में आकार हमेशा निश्चित लंबाई के होते हैं, लेकिन ऐसा तरीका है जिसमें आप गतिशील रूप से रंटे खुद पर आकार को बढ़ा सकते हैं

यह सबसे "उपयोग किया जाता है" और साथ ही इसे करने का पसंदीदा तरीका है-

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

उपरोक्त कोड में हम एक नए अस्थायी [] सरणी को शुरू कर रहे हैं, और आगे मूल सरणी की सामग्री के साथ अस्थायी की सामग्री को आरंभीकृत करने के लिए एक लूप का उपयोग कर रहे हैं। stck []। और फिर इसे फिर से मूल एक में कॉपी करना, हमें नए आकार का एक नया सरणी देना।

कोई संदेह नहीं है कि यह लूप के लिए बार-बार उपयोग कर एक सरणी को फिर से संगठित करने के कारण एक सीपीयू ओवरहेड उत्पन्न करता है। लेकिन आप अभी भी इसे अपने कोड में उपयोग और कार्यान्वित कर सकते हैं। एरे के बजाय "लिंक्ड लिस्ट" के सर्वोत्तम अभ्यास के लिए, यदि आप चाहते हैं कि डेटा को डायनामिक रूप से मेमोरी में, वैरिएबल लंबाई के लिए संग्रहीत किया जाए।

यहां रन-टाइम में ARRAY SIZE को डायनेमिक स्टैक्स पर आधारित एक रियल-टाइम उदाहरण दिया गया है

फ़ाइल-नाम: 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);

}

}

आशा है कि यह आपकी क्वेरी को हल करता है।


0

हां, हम इस तरह से कर सकते हैं।

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

चूँकि ArrayList को बहुत अधिक मेमोरी लगती है, जब मुझे आदिम प्रकार की सरणी की आवश्यकता होती है, मैं int array बनाने के लिए 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();

नोट: जावा 8 से उपलब्ध है।


0

आप कुछ कर सकते हैं

private  static Person []  addPersons(Person[] persons, Person personToAdd) {
    int currentLenght = persons.length;

    Person [] personsArrayNew = Arrays.copyOf(persons, currentLenght +1);
    personsArrayNew[currentLenght]  = personToAdd;

    return personsArrayNew;

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.