একটি অ্যারে কেন ইটেটেবলের জন্য নির্ধারিত হয় না?


186

জাভা 5 এর সাথে আমরা লিখতে পারি:

Foo[] foos = ...
for (Foo foo : foos) 

বা লুপের জন্য কেবল একটি Iteable ব্যবহার করে। এটি খুব সহজ।

তবে আপনি এর মতো পুনরাবৃত্তির জন্য জেনেরিক পদ্ধতি লিখতে পারবেন না:

public void bar(Iterable<Foo> foos) { .. }

এবং এটিকে অ্যারে দিয়ে কল করা যেহেতু এটি কোনও মূল্যবান নয়:

Foo[] foos = { .. };
bar(foos);  // compile time error 

আমি এই নকশার সিদ্ধান্তের পিছনে কারণগুলি নিয়ে ভাবছি।


8
অ্যারে.এএসলিস্টটি আমার মনে হয় যথেষ্ট ভাল
dfa

17
এটি একটি দার্শনিক প্রশ্ন
ডিএফএ

2
জাভা 5+ এ অ্যারে নিয়ে কাজ করার একটি ভাল কারণ হ'ল ভ্যারাগস পদ্ধতি।
জেফ ওয়াকার 16

2
@ টর্স্টেন: সত্য, তবে আপনি যদি এমন কোনও পদ্ধতিতে পাস করেন যা একটি আইটেবল গ্রহণ করে তবে আপনি সম্ভবত কোনও পরিবর্তন করবেন না।
মাইকেল ম্যাইইয়ার্স

5
আসলে, অ্যারে.এএসলিস্ট যথেষ্ট ভাল নয় কারণ এটি আদিম ধরণের অ্যারেগুলিতে কাজ করে না। আদিম ধরণের উপাদানগুলিকে সাধারণভাবে পুনরাবৃত্তি করার (বাক্সযুক্ত) একমাত্র অন্তর্নির্মিত উপায় হ'ল ব্যবহার করে java.lang.reflect.Array, তবে এর কার্যকারিতা দুর্বল। তবে আপনি চাইলে আদিম ধরণের অ্যারেগুলিকে গুটিয়ে রাখতে আপনার নিজের পুনরাবৃত্তকারী (বা তালিকা প্রয়োগকরণের তালিকা) লিখতে পারেন।
বোয়ান

উত্তর:


78

অ্যারে ইন্টারফেস ( Cloneableএবং java.io.Serializable) প্রয়োগ করতে পারে । তাহলে কেন হবে না Iterable? আমি অনুমান করি যে Iterableকোনও iteratorপদ্ধতি যুক্ত করার জন্য বাহিনী , এবং অ্যারেগুলি পদ্ধতি প্রয়োগ করে না। char[]এমনকি ওভাররাইডও করে না toString। যাইহোক, রেফারেন্সগুলির অ্যারেগুলি আদর্শ - ব্যবহারের চেয়ে কম বিবেচনা করা উচিত List। ডিএফএ মন্তব্য হিসাবে, Arrays.asListআপনার জন্য রূপান্তরটি স্পষ্টভাবে করবে।

(এটি বলার পরে, আপনি cloneঅ্যারেতে কল করতে পারেন ))


23
> "... এবং অ্যারে পদ্ধতিগুলি প্রয়োগ করে না।" আমি মনে করি এটি অন্য দার্শনিক প্রশ্ন; অ্যারেগুলি কখনও আদিম ধরণের ছিল না, এবং জাভা দর্শনে পড়েছিল যে "সবকিছুই একটি বস্তু (আদিম প্রকার বাদে)" "। তাহলে, অ্যারে পদ্ধতিগুলি বাস্তবায়িত করে না যদিও গাজিলিয়ন অপারেশন রয়েছে যেগুলি শুরু থেকে একজন অ্যারে ব্যবহার করতে চায়। ওহ, এটি ঠিক, জেনেরিকস আফসোস হিন্ডসাইট হিসাবে আসার আগে অ্যারেগুলি কেবলমাত্র দৃ strongly়ভাবে টাইপ করা সংগ্রহ ছিল।
ফতুহোকু

2
যদি আপনি কোনও অ্যারেতে ডেটা পেয়ে থাকেন তবে এটি সম্ভব যে আপনি নিম্ন-স্তরের, পারফরম্যান্স সমালোচনামূলক কাজ যেমন স্ট্রিম থেকে বাইট [] এর পড়ার বিষয়টি নিয়ে কাজ করা। অ্যারেগুলি পুনরাবৃত্তি করতে অক্ষমতা সম্ভবত জাভা জেনেরিকদের কাছ থেকে উদ্ভূত হয়েছে যেমন আর্গুমেন্টগুলিকে টাইপ আর্গুমেন্ট হিসাবে সমর্থন করে না, যেমন নীচে @ গ্যারেথ বলেছে।
ড্রয় নোকস

2
@ ফাতুহোকু জেনারিকসটির পরামর্শ দিচ্ছিল যে দুঃখজনকভাবে ভুল ছিল। জেনেরিকদের আকাঙ্ক্ষা সর্বদা প্রশংসা করা হয়েছিল। অ্যারেগুলি আদিম নয় (আমি বলিনি যে তারা ছিল) তবে তারা নিম্ন স্তরের। অ্যারেগুলির সাথে আপনি যে জিনিসটি করতে চান তা হ'ল এগুলি ভেক্টর-জাতীয় কাঠামোর জন্য প্রয়োগের বিশদ হিসাবে ব্যবহার করুন।
টম হাটিন -

1
Iterator<T>এছাড়াও এটি প্রয়োজন remove(T), যদিও এটি একটি নিক্ষেপ করার অনুমতি দেওয়া হয় UnsupportedOperationException
wchargin

অ্যারে পদ্ধতিগুলি প্রয়োগ করে: তারা সমস্ত পদ্ধতি প্রয়োগ করে java.lang.Object
মোহাম্মিথ

59

অ্যারেটি একটি অবজেক্ট তবে এর আইটেমগুলি নাও হতে পারে। অ্যারেটি ইন্টের মতো একটি আদিম ধরণের ধারণ করতে পারে যা Iterable এর সাথে মানিয়ে নিতে পারে না। কমপক্ষে আমি এটাই গণনা করি।


3
এর অর্থ Iterableইন্টারফেসটি সমর্থন করার জন্য , মোড়ক ক্লাসগুলি ব্যবহার করার জন্য আদিম অ্যারেগুলিকে বিশেষজ্ঞ করতে হবে। এগুলির কিছুই সত্যিই বড় বিষয় নয়, যেহেতু টাইপ প্যারামিটারগুলি যাইহোক সমস্ত নকল।
thejoshwolfe

8
এটি অবজেক্ট অ্যারেগুলিকে ইটেবারে প্রয়োগ থেকে আটকাবে না। এটি মোড়ানো প্রকারের জন্য Iteable প্রয়োগের থেকে আদিম অ্যারেগুলিকে বাধা দেয় না।
বোয়ান

1
অটোবক্সিং এটি পরিচালনা করতে পারে
টিম বাথ

আমি মনে করি এটি সঠিক কারণ। জেনেরিক্স আদিম প্রকারগুলিকে সমর্থন না করা পর্যন্ত (যেমন, List<int>পরিবর্তে List<Integer>ইত্যাদি) আধ্যাত্মিকভাবে কাজ করবে না until একটি হ্যাক মোড়ক দিয়ে করা যেতে পারে তবে পারফরম্যান্সের ক্ষতিতে - এবং আরও গুরুত্বপূর্ণ - যদি এই হ্যাকটি করা হয়ে থাকে তবে ভবিষ্যতে জাভাতে এটি সঠিকভাবে প্রয়োগ করা আটকাবে না (উদাহরণস্বরূপ পরিবর্তে int[].iterator()চিরতরে ফিরে আসার জন্য লক হয়ে থাকবে )। সম্ভবত, আসন্ন মান-প্রকারের + জাজের জন্য জেনেরিক-বিশেষায়িতকরণ (প্রকল্পের ভালাল্লা) অ্যারেগুলি কার্যকর করবে । Iterator<Integer>Iterator<int>Iterable
বজার্কে

16

অ্যারেগুলিকে সমর্থন করা উচিত Iterable, তারা ঠিক একই কারণে নয় যে .NET অ্যারে এমন একটি ইন্টারফেস সমর্থন করে না যা অবস্থান অনুসারে পাঠ্যভাবে এলোমেলো অ্যাক্সেসের অনুমতি দেয় (স্ট্যান্ডার্ড হিসাবে সংজ্ঞায়িত এমন কোনও ইন্টারফেস নেই)। মূলত ফ্রেমওয়ার্কগুলিতে প্রায়শই বিরক্তিকর সামান্য ব্যবধান থাকে যা কারও পক্ষে ঠিক করা সময় মতো নয়। আমরা তাদের কিছু অনুকূল উপায়ে তাদের ঠিক করতে পারি কিনা তাতে কিছু আসে যায় না, তবে প্রায়ই আমরা তা পারি না।

আপডেট: সমান হাত পেতে, আমি উল্লেখ করেছি। নেট অ্যারেগুলি এমন ইন্টারফেসকে সমর্থন করছে না যা অবস্থান অনুসারে এলোমেলো অ্যাক্সেস সমর্থন করে (আমার মন্তব্যটিও দেখুন)। কিন্তু নেট 4.5.৪ এ সেই সঠিক ইন্টারফেসটি সংজ্ঞায়িত করা হয়েছে এবং অ্যারে এবং List<T>ক্লাস দ্বারা সমর্থিত :

IReadOnlyList<int> a = new[] {1, 2, 3, 4};
IReadOnlyList<int> b = new List<int> { 1, 2, 3, 4 };

সবগুলি এখনও পুরোপুরি নিখুঁত নয় কারণ পরিবর্তনীয় তালিকার ইন্টারফেসটি IList<T>উত্তরাধিকারসূত্রে পাওয়া যায় না IReadOnlyList<T>:

IList<int> c = new List<int> { 1, 2, 3, 4 };
IReadOnlyList<int> d = c; // error

এই জাতীয় পরিবর্তনের সাথে একটি পশ্চাদপটে সামঞ্জস্যের সম্ভাবনা রয়েছে।

জাভা এর নতুন সংস্করণে অনুরূপ বিষয়ে যদি কোনও অগ্রগতি হয় তবে আমি মন্তব্যগুলিতে জানতে আগ্রহী হব! :)


8
.NET অ্যারেগুলি IList ইন্টারফেসটি প্রয়োগ করে
টম গিলেন

2
@ এফিড - আমি কেবলমাত্র র্যান্ডম অ্যাক্সেসের কথা বলেছি । IList<T>সংশোধন করার জন্য অপারেশন প্রকাশ করে। এটা বড় হতে তাহলে IList<T>একটি ভালো কিছু উত্তরাধিকারসূত্রে ছিল IReadonlyList<T>ইন্টারফেস, যা ঠিক ছিল যেত Countএবং T this[int]এবং উত্তরাধিকারসূত্রে IEnumerable<T>(যা ইতিমধ্যে কেবলমাত্র শুমার সমর্থন করে)। আর একটি দুর্দান্ত জিনিস ReverseCountICollection
হ'ল

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

1
.NET ক্ষেত্রে বিন্যাসগুলির বাস্তবায়ন IListICollection.NET 1.1 থেকে, এবং IList<T>এবং ICollection<T>.NET 2.0 থেকে। এটি আরও একটি ঘটনা যেখানে জাভা প্রতিযোগিতার চেয়ে অনেক পিছিয়ে রয়েছে।
আমির আবির

@ টম গিলেন: আমার সবচেয়ে বড় সমস্যাটি IListহ'ল এটি আরও অনুসন্ধানযোগ্য বৈশিষ্ট্য সরবরাহ করে না। আমি বলব যে একটি উপযুক্ত সেটটিতে ইস্পুটেটেবল, ইসরাইজেবল, ইসরডিডোনালি, ইসফিক্সডসাইজ এবং স্টার্টিংয়ের জন্য বিদ্যমান উপাদানসমূহআরআইমুট্যাবল অন্তর্ভুক্ত করা উচিত। কোড কোনও রেফারেন্স, টাইপকাস্টিং ছাড়াই, কোনও তালিকা সংশোধন করতে পারে কিনা এই প্রশ্নটি যে কোডের সাথে একটি তালিকা রেফারেন্স ধারণ করে যা সংশোধন করার কথা নয় এটি নিরাপদে সেই রেফারেন্সটি সরাসরি বাইরের কোডের সাথে ভাগ করতে পারে কিনা সে প্রশ্নগুলির থেকে পৃথক কিনা, বা কিনা এটি নিরাপদে ধরে নিতে পারে তালিকার কিছু দিকটি কখনই পরিবর্তিত হবে না।
সুপারক্যাট

14

দুর্ভাগ্যক্রমে, অ্যারেগুলি ' class-রকম' নয়। তারা বাস্তবায়ন করে নাIterable ইন্টারফেস ।

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

আপনি প্রতিটি লুপের জন্য এগুলি ব্যবহার করতে পারেন কারণ সান অ্যারেগুলির জন্য কিছু সিনট্যাটিক চিনির সাথে যোগ করেছেন (এটি একটি বিশেষ ক্ষেত্রে)।

যেহেতু অ্যারেগুলি জাভা 1 এর সাথে 'প্রায় অবজেক্টস' হিসাবে শুরু হয়েছিল, তাই জাভাতে তাদের সত্যিকারের বস্তু তৈরি করা কোনও পরিবর্তন হওয়া খুব কঠোর হবে ।


14
তবুও, প্রতিটি লুপের জন্য চিনি রয়েছে, তবে কেন ইটারেবলের জন্য চিনি থাকতে পারে না?
মাইকেল ময়র্স

8
@ এমমিয়ার্স: প্রতিটি জন্য ব্যবহৃত চিনি সংকলন-সময় চিনির হয়। এটি ভিএম চিনির চেয়ে অনেক সহজ কাজ । যা বলার পরে, নেট নেটওয়ার্কগুলি এই অঞ্চলে উল্লেখযোগ্যভাবে আরও ভাল ...
জন স্কিইট

12
অ্যারে ইন্টারফেস প্রয়োগ করতে পারে । তারা বাস্তবায়ন Cloneableএবং Serializableইন্টারফেস।
16:42

34
জাভা অ্যারে সমস্ত ইন্দ্রিয়ের বস্তু। দয়া করে সেই ভুল তথ্যটি দূর করুন। তারা কেবল আইটেবল প্রয়োগ করে না।
ykaganovich

5
একটি অ্যারে একটি অবজেক্ট। এটি দরকারী সমর্থন করে : পি পদ্ধতিগুলি যেমন অপেক্ষা (), অপেক্ষা (এন), অপেক্ষা (এন, এম), বিজ্ঞপ্তি (), নোটিফাইএল (), চূড়ান্তকরণ (), টু স্ট্রিংয়ের একটি অর্থহীন বাস্তবায়ন () একমাত্র দরকারী পদ্ধতিটি getClass () ।
পিটার লরি

1

সংকলক আসলে for eachএকটি অ্যারেতে অনুলিপিটিকে সরল রূপে অনুবাদ করেfor অনকে একটি পাল্টা ভেরিয়েবলের সাথে একটি লুপে ।

নিম্নলিখিত সংকলন

public void doArrayForEach() {
    int[] ints = new int[5];

    for(int i : ints) {
        System.out.println(i);
    }
}

এবং তারপরে .class ফাইলের ফলন পচিয়ে

public void doArrayForEach() {
    int[] ints = new int[5];
    int[] var2 = ints;
    int var3 = ints.length;

    for(int var4 = 0; var4 < var3; ++var4) {
        int i = var2[var4];
        System.out.println(i);
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.