সংগ্রহকে অ্যারেতে রূপান্তরিত করার সহজতম উপায়?


125

মনে করুন আমাদের একটি আছে Collection<Foo>। এটিকে রূপান্তর করার সবচেয়ে ভাল উপায় (বর্তমান প্রসঙ্গে এলওসি-তে সবচেয়ে কম) Foo[]কী? যে কোনও সুপরিচিত গ্রন্থাগার অনুমোদিত।

UPD; কি রূপান্তর সম্পর্কে (এই বিভাগে আরও একটি ক্ষেত্রে ছুটি মন্তব্য যদি আপনি এটি এর মূল্য এটা জন্য অন্য থ্রেড তৈরি করার জন্য মনে করি) Collection<Foo>থেকে Bar[]যেখানে Barটাইপ 1 পরামিতি সঙ্গে কনস্ট্রাকটর নেই তা Fooঅর্থাত public Bar(Foo foo){ ... }?


অনুরূপ কর্মক্ষমতা এবং এর সাথে ব্যাখ্যা সহ একই ক্রিয়াকলাপটি সম্পাদন করতে জেডিকে -11 এ প্রবর্তিত বিকল্প এপিআই দিয়ে এই উত্তরটি তৈরি করুন । প্লাস সিনট্যাক্সটি Stream.toArrayজেডিকে থেকে বিদ্যমান এপিআইয়ের সাথে মেলে ।
নমন

উত্তর:


256

xসংগ্রহটি কোথায় :

Foo[] foos = x.toArray(new Foo[x.size()]);

35
সহজ (সহজ) তবে সেরা নয় (স্মৃতি): x.toArray(new Foo[0]) --- ডকুমেন্টেশন : পড়ার সময় নেই ...
ব্যবহারকারীর 85421

6
@ কার্লোস আসলে এটির চেয়ে ভাল মেমরি ব্যবহার করে (new Foo[0])। কালেকশন.টো অ্যারির ডকুমেন্টেশন অনুসারে, `@ একটি অ্যারে তৈরি করুন যাতে এই সংগ্রহের উপাদানগুলি সংরক্ষণ করতে হয়, যদি এটি যথেষ্ট পরিমাণে বড় হয় - যার অর্থ এটি সরাসরি সেই নতুন অ্যারেতে সংরক্ষণ করবে। আপনি যদি এটির আকার 0 অ্যারে দেন তবে এটি একটি নতুন অ্যারে তৈরি করবে, যার অর্থ আপনার অল্প অरे রয়েছে এবং যখন এটি অপ্রয়োজনীয় হয় তখন একটি বড় অ্যারে তৈরি করা হয়।
কর্সিকা

4
@ গ্লোকোডার - তবে আপনি যদি একটি স্ট্যাটিক ধ্রুবক হিসাবে একবার খালি অ্যারে সংজ্ঞা দেন তবে এটি হ্রাস করা যেতে পারে। toArrayসঠিক ধরণের একটি টার্গেট অ্যারে তৈরির জন্য এটি কেবল একটি ইঙ্গিত । এবং এই ক্ষেত্রে, সত্যি বলতে, আমি আমার অ্যাপ্লিকেশনটিতে একটি অতিরিক্ত একক খালি অ্যারের যত্ন নেব না। এটি গোলমাল স্তর থেকে অনেক নিচে।
আন্দ্রেয়াস ডলক

2
@ গ্লোকোডার - ঠিক এই কারণেই আমি ( চেষ্টা করে ) লিখেছি যে ব্যবহার new Foo[0]করা সহজ "তবে সবচেয়ে ভাল নয় (স্মৃতি)" ... অর্থাৎ, আমি বোঝাতে চেয়েছিলাম যে আমার সমাধানটি সহজ তবে সবচেয়ে ভাল নয় (এই কারণেই আমি ব্যবহার করেছি :)।
ব্যবহারকারী 85421

21
মনে রাখবেন যে এই কোডটি থ্রেডসেফ নয়, এমনকি আপনি সিঙ্ক্রোনাইজ করা সংগ্রহ ব্যবহার করছেন using এটি বেশিরভাগ পরিস্থিতিতে নিজের আচরণ করবে, তবে x.size () এবং x.toArray () এর কলটির মধ্যে যদি কোনও আইটেম মুছে ফেলা হয়, ফলস্বরূপ অ্যারেটিতে অতিরিক্ত নাল উপাদান থাকবে। new Foo[0]বৈকল্পিক কার্লোস দ্বারা প্রস্তাবিত এই সমস্যা ভোগ করে না।
জুলস

36

জাভা 8 ব্যবহার করে আপডেট হওয়া প্রশ্নের বিকল্প সমাধান:

Bar[] result = foos.stream()
    .map(x -> new Bar(x))
    .toArray(size -> new Bar[size]);

35
এটি সংক্ষিপ্ত করা যেতে পারে Bar[] result = foos.stream().map(Bar::new).toArray(Bar[]::new);
lpandzic

সিনট্যাক্স অনুযায়ী আমি গ্রহণযোগ্য উত্তর পছন্দ করতে চাই। আমি আশা করি লোকেরা সবাই পাইথনে যেতে পারে।
এরিক চেন

@ এরিকচেন পাইথনে স্যুইচ করুন - জাভা থেকে একটি ব্যাখ্যা করা এবং গতিশীল টাইপ করা ভাষা - কোডিং সিনট্যাক্স এবং সংখ্যার লাইনগুলির কারণে 'সংকলিত এবং স্ট্যাটিকালি টাইপ করা ভাষা' আলাদা হয়? ভালো বুদ্ধি নই.
রাফিআলহামদ

10

আপনি যদি এটি একাধিকবার বা লুপে ব্যবহার করেন তবে আপনি একটি ধ্রুবককে সংজ্ঞায়িত করতে পারেন

public static final Foo[] FOO = new Foo[]{};

এবং রূপান্তরটি পছন্দ করুন do

Foo[] foos = fooCollection.toArray(FOO);

toArrayপদ্ধতি খালি অ্যারে নিতে লক্ষ্য অ্যারের সঠিক টাইপ নির্ধারণ করার জন্য এবং আপনার জন্য একটি নতুন অ্যারে তৈরি করবে।


আপডেটের জন্য আমার প্রস্তাবটি এখানে:

Collection<Foo> foos = new ArrayList<Foo>();
Collection<Bar> temp = new ArrayList<Bar>();
for (Foo foo:foos) 
    temp.add(new Bar(foo));
Bar[] bars = temp.toArray(new Bar[]{});

1
আপস, constজাভা না! public static final Foo[] FOO = {}
ব্যবহারকারী 85421

1
এটা কেন প্রকাশ্য হবে?
জুলটান

@ জোল্টন - কেন নয়? এটি পরিবর্তনযোগ্য, সুতরাং কোনও সুরক্ষা সমস্যা উপস্থাপন করে না। এটি কিছুটা বিশৃঙ্খলা, তবে অন্যান্য কোডে কার্যকর হতে পারে, তাই সাধারণত নিরীহ is এমনকি এই সমস্ত ধ্রুবক সহ একটি কেন্দ্রীয় বর্গ তৈরি করতে পারেন এবং তারপরে এগুলি import staticপেতে ব্যবহার করুন।
জুলস

@ জুলে অ্যারের রেফারেন্সটি অপরিবর্তনীয় তবে এর লিখিত সামগ্রীটি নেই। শ্রেণীর বাইরের যে কেউ অ্যারের উপাদানগুলি অবাধে প্রতিস্থাপন করতে পারে can এবং অন্যদিকে, থাম্বের নিয়ম হিসাবে, আমি বিশ্বাস করি যে সমস্ত ক্ষেত্র শ্রেণীর বাইরে প্রয়োজন না হওয়া অবধি তাদের ব্যক্তিগত করা উচিত।
জোল্টন

2
শূন্য দৈর্ঘ্যের কারণে, এমন কোনও সামগ্রী নেই যা পরিবর্তন করা যায়
জুলস

5

জেডিকে / ১১ এর সাহায্যে এটিকে রূপান্তর Collection<Foo>করার একটি বিকল্প উপায় হিসাবে এটি Foo[]ব্যবহার করা যেতে পারে Collection.toArray(IntFunction<T[]> generator):

Foo[] foos = fooCollection.toArray(new Foo[0]); // before JDK 11
Foo[] updatedFoos = fooCollection.toArray(Foo[]::new); // after JDK 11

দ্বারা ব্যাখ্যা হিসাবে মেইলিং তালিকা @Stuart (জোর খনি) এই কর্মক্ষমতা মূলত বিদ্যমান যে একই হওয়া উচিত Collection.toArray(new T[0])-

উত্সাহটি হ'ল যে প্রয়োগগুলি ব্যবহার করে Arrays.copyOf() এটি দ্রুততম হয়, সম্ভবত এটি একটি অন্তর্গত

এটি নতুনভাবে বরাদ্দ হওয়া অ্যারে শূন্য-পূরণ করা এড়াতে পারে কারণ এটি জানে যে পুরো অ্যারের সামগ্রীগুলি ওভাররাইট করা হবে। পাবলিক এপিআইয়ের চেহারা নির্বিশেষে এটি সত্য।

জেডিকে-র মধ্যে এপিআইয়ের বাস্তবায়নটি পড়ে:

default <T> T[] toArray(IntFunction<T[]> generator) {
    return toArray(generator.apply(0));
}

ডিফল্ট বাস্তবায়ন generator.apply(0)শূন্য দৈর্ঘ্যের অ্যারে পেতে কল করে এবং পরে কেবল কল করে toArray(T[])। এটি Arrays.copyOf() দ্রুতগতির মধ্য দিয়ে যায় তাই এটি মূলত একই গতি toArray(new T[0])


দ্রষ্টব্য : -মানগুলিসহ কোডের জন্য যখনএপিআই ব্যবহার করা হবেতখন পশ্চাদপটে অসঙ্গতি সহ পরিচালনা করা হবেnullযেমনtoArray(null)এই কলগুলি এখন বিদ্যমান কারণে অস্পষ্টtoArray(T[] a)এবং সংকলন করতে ব্যর্থ হবে।



3

আসল দেখুন ডাবল উত্তর:

Foo[] a = x.toArray(new Foo[x.size()]);

আপডেট হিসাবে:

int i = 0;
Bar[] bars = new Bar[fooCollection.size()];
for( Foo foo : fooCollection ) { // where fooCollection is Collection<Foo>
    bars[i++] = new Bar(foo);
}    

3

আপডেট বিভাগে (গুগল সংগ্রহের সহায়তায়) মামলার চূড়ান্ত সমাধান এখানে দেওয়া হয়েছে:

Collections2.transform (fooCollection, new Function<Foo, Bar>() {
    public Bar apply (Foo foo) {
        return new Bar (foo);
    }
}).toArray (new Bar[fooCollection.size()]);

তবে, এখানে মূল পদ্ধতির দ্বিগুণের উত্তরে উল্লেখ করা হয়েছিল (আমি toArrayপদ্ধতির জন্য ভুলে গেছি )।


1
থ্রেড সুরক্ষা সম্পর্কে ডাবলের উত্তর সম্পর্কে আমার মন্তব্য দেখুন, যা এই সমাধানটিতেও প্রযোজ্য। new Bar[0]বিষয়টি এড়িয়ে যায়।
জুলস

-1

উদাহরণস্বরূপ, আপনার কাছে উপাদান শ্রেণীর উপাদানগুলির সাথে অ্যারেলিস্ট রয়েছে:

List stuList = new ArrayList();
Student s1 = new Student("Raju");
Student s2 = new Student("Harish");
stuList.add(s1);
stuList.add(s2);
//now you can convert this collection stuList to Array like this
Object[] stuArr = stuList.toArray();           // <----- toArray() function will convert collection to array
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.