জাভা গতিশীল অ্যারের আকার?


106

আমার ক্লাস আছে - এক্সক্লাস, আমি এক্সক্লাসের একটি অ্যারেতে লোড করতে চাই তাই আমি ঘোষণাটি দিয়েছি:

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

তবে, আমার 10 দরকার হবে কিনা তা আমি জানি না 10 আমার এই বিষয়ে 8 বা 12 বা অন্য কোনও নম্বর লাগতে পারে। আমি রানটাইম পর্যন্ত জানি না। আমি কি উড়ে একটি অ্যারে উপাদানের সংখ্যা পরিবর্তন করতে পারি? যদি তাই হয়, কিভাবে?


আমি প্রশ্নের ফর্ম্যাটিং স্থির করেছি, আপনি চাইলে কেবল শিরোনাম করতে পারেন, বর্ণনামূলক হবেন। এবং স্ট্যাকওভারফ্লোতে স্বাগতম! : ডি
গর্ডন গুস্তাফসন

উত্তর:


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
তালিকাটি ইন্টারফেস এবং অ্যারেলিস্ট হ'ল বাস্তবায়ন। এটিকে অ্যারেলিস্ট হিসাবে তৈরি করা তবে এটিকে তালিকা হিসাবে উল্লেখ করা (যাতে এটি পরে পরিবর্তিত হতে পারে) সঠিক।
সিবিগ্রাহাম

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

অন্যরা যেমন বলেছে, আপনি বিদ্যমান জাভা অ্যারের আকার পরিবর্তন করতে পারবেন না।

অ্যারেলিস্ট স্ট্যান্ডার্ড জাভাটির একটি গতিশীল আকারের অ্যারের সবচেয়ে কাছাকাছি। তবে অ্যারেলিস্ট সম্পর্কে কিছু জিনিস রয়েছে (আসলে তালিকার ইন্টারফেস) যা "অ্যারে লাইক" নয়। উদাহরণ স্বরূপ:

  • আপনি [ ... ]একটি তালিকা সূচী ব্যবহার করতে পারবেন না । আপনাকে get(int)এবং set(int, E)পদ্ধতিগুলি ব্যবহার করতে হবে ।
  • একটি অ্যারেলিস্ট শূন্য উপাদান সহ তৈরি করা হয়। আপনি 20 টি উপাদান দিয়ে আরেলিস্ট তৈরি করতে পারবেন না এবং কল করতে পারবেন set(15, foo)
  • আপনি সরাসরি অ্যারেলিস্টের আকার পরিবর্তন করতে পারবেন না। আপনি পরোক্ষভাবে বিভিন্ন ব্যবহার করে এটি কি add, insertএবং removeপদ্ধতি।

আপনি যদি আরও অ্যারে-জাতীয় কিছু চান তবে আপনার নিজের এপিআই ডিজাইন করতে হবে। (হয়তবা বিদ্যমান তৃতীয় পক্ষের লাইব্রেরিটি দিয়ে কেউ আঁকতে পারে ... গুগল ব্যবহার করে আমি 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

আপনি অ্যারেলিস্ট ব্যবহার করতে পারেন:

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 (মাইক্র্লাস, i + 1); মাইস্ক্লাস [i] = নতুন মাই ক্লাস ();
মিশা বার্গার

2

হ্যাঁ, এটি মোড়ানো এবং সংগ্রহের কাঠামোটি ব্যবহার করুন।

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

তারপরে প্রয়োজনে তালিকা. টুআর্রে () ব্যবহার করুন, অথবা কেবলমাত্র তালিকাটির উপরে পুনরাবৃত্তি করুন।


2

অন্য ব্যবহারকারীরা যেমন বলেছেন, আপনার সম্ভবত java.util.List একটি বাস্তবায়ন প্রয়োজন।

যদি, কোনও কারণে, আপনার শেষ পর্যন্ত অ্যারের প্রয়োজন হয় তবে আপনি দুটি জিনিস করতে পারেন:

  • একটি তালিকা ব্যবহার করুন এবং তারপরে এটিকে myList.toArray () দিয়ে অ্যারেতে রূপান্তর করুন)

  • নির্দিষ্ট আকারের একটি অ্যারে ব্যবহার করুন। আপনার যদি কম বা কম আকারের প্রয়োজন হয় তবে আপনি এটি java.util.Arrays পদ্ধতিতে পরিবর্তন করতে পারেন।

সেরা সমাধান আপনার সমস্যার উপর নির্ভর করবে;)


2

আমি পরিবর্তে ভেক্টর ব্যবহার করার পরামর্শ দিচ্ছি। ব্যবহার করা খুব সহজ এবং বাস্তবায়নের জন্য অনেক পূর্বনির্ধারিত পদ্ধতি রয়েছে।

import java.util.*;

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

কোনও উপাদান যুক্ত করতে কেবল ব্যবহার করুন:

v.addElement(int);

ইন (5,2) প্রথম 5 ভেক্টর প্রাথমিক আকার। আপনি যদি প্রাথমিক আকারটি অতিক্রম করেন তবে ভেক্টরটি 2 স্থান বাড়বে। যদি এটি আবার অতিক্রম করে, তবে এটি আবার ২ টি স্থান এবং আরও অনেক কিছু দিয়ে বাড়বে।


4
আপনার বিশেষত থ্রেড-সেফ (-ish) প্রকারের প্রয়োজন না হলে আপনার ভেক্টরের চেয়ে অ্যারেলিস্ট ব্যবহার করা উচিত।
স্টিফেন সি

1

আপনি যেখানে মাইক্লাস [] অ্যারে হিসাবে ঘোষণা করবেন:

xClass myclass[] = new xClass[10]

, কেবলমাত্র যুক্তি হিসাবে আপনার প্রয়োজনীয় XClass উপাদানগুলির সংখ্যাটি প্রবেশ করুন। এই মুহুর্তে আপনি জানেন যে আপনার কতজনের প্রয়োজন হবে? অ্যারে 10 টি উপাদান হিসাবে ঘোষণা করে আপনি 10 টি এক্সক্লাস বস্তু ঘোষণা করছেন না, আপনি কেবল এক্সক্লাস টাইপের 10 উপাদান দিয়ে একটি অ্যারে তৈরি করছেন।


1

জাভা অ্যারের আকারগুলি স্থির হয়ে গেছে, আপনি সি ++ এর মতো গতিশীল অ্যারেগুলি তৈরি করতে পারবেন না।


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

এটি আপনার অ্যারের আকারকে এক্স সময় হিসাবে রান সময় প্রবিষ্ট করা হিসাবে নির্ধারিত করে।


0

এখানে একটি পদ্ধতি যা অ্যারেলিস্ট ব্যবহার করে না। ব্যবহারকারী আকারটি নির্দিষ্ট করে এবং আপনি পুনরাবৃত্তির জন্য একটি ডু-ওয়েল লুপ যুক্ত করতে পারেন।

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 []। এবং তারপরে আবার এটি আবার আসলটিকে অনুলিপি করে আমাদেরকে নতুন সাইজের একটি নতুন অ্যারে প্রদান করে।

সন্দেহ নেই যে এটি বারবার লুপের জন্য ব্যবহার করে অ্যারেটিকে পুনরায় পুনরায় তৈরি করার কারণে একটি সিপিইউ ওভারহেড তৈরি করে। তবে আপনি এখনও এটি আপনার কোডটিতে ব্যবহার এবং প্রয়োগ করতে পারেন। সেরা অনুশীলনের জন্য অ্যারের পরিবর্তে "লিঙ্কড লিস্ট" ব্যবহার করুন, আপনি যদি পরিবর্তনশীল দৈর্ঘ্যের মেমরিতে ডেটা গতিশীলভাবে সংরক্ষণ করতে চান।

রান-টাইমে ক্রমবর্ধমান এয়ার সাইজে ডায়নামিক স্ট্যাকের উপর ভিত্তি করে এখানে একটি রিয়েল-টাইম উদাহরণ রয়েছে

ফাইলের নাম: ডিএসট্যাক.জভা

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

}

ফাইলের নাম: এক্সিকিউজ.জাভা
(মূল শ্রেণীর সাথে)

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

যেহেতু আমার প্রারম্ভিক ধরণের অ্যারে দরকার হয় তখন অ্যারেলিস্টটি অনেক বেশি স্মৃতিতে নিয়ে যায়, তাই ইনট অ্যারে তৈরি করার জন্য আমি ইনটস্ট্রিম.বিল্ডার () ব্যবহার করতে পছন্দ করি (আপনি লংস্ট্রিম এবং ডাবলস্ট্রিম বিল্ডারও ব্যবহার করতে পারেন)।

উদাহরণ:

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;

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.