জাভাতে লিংকডলিস্টগুলির একটি অ্যারে তৈরি করা যায় না ...?


102

আমি একটি বিচ্ছিন্ন ম্যাট্রিক্স ক্লাসে কাজ করছি যা ম্যাট্রিক্সের মানগুলি সংরক্ষণ করার জন্য একটি অ্যারে ব্যবহার করা দরকারLinkedList । অ্যারের প্রতিটি উপাদান (অর্থাত্ প্রতিটি LinkedList) ম্যাট্রিক্সের একটি সারি উপস্থাপন করে। এবং LinkedListঅ্যারের প্রতিটি উপাদান একটি কলাম এবং সঞ্চিত মান উপস্থাপন করে।

আমার ক্লাসে, আমার কাছে অ্যারের একটি ঘোষণা আছে:

private LinkedList<IntegerNode>[] myMatrix;

এবং, আমার নির্মাতার মধ্যে SparseMatrix, আমি সংজ্ঞা দেওয়ার চেষ্টা করি:

myMatrix = new LinkedList<IntegerNode>[numRows];

আমি যে ত্রুটিটি পেয়েছি তা হ'ল

এর জেনেরিক অ্যারে তৈরি করা যায় না LinkedList<IntegerNode>

সুতরাং, আমার এই দুটি সমস্যা আছে:

  1. আমি কি ভুল করছি, এবং
  2. অ্যারের জন্য প্রজ্ঞাপনে টাইপটি গ্রহণযোগ্য যদি এটি তৈরি না করা যায়?

IntegerNodeআমি তৈরি করেছি এমন একটি ক্লাস। এবং, আমার ক্লাসের সমস্ত ফাইল একত্রে প্যাকেজ করা আছে।

উত্তর:


64

আপনি জেনেরিক অ্যারে তৈরি ব্যবহার করতে পারবেন না। এটি জাভা জেনেরিকের একটি ত্রুটি / বৈশিষ্ট্য।

সতর্কতা ব্যতীত উপায়গুলি হ'ল:

  1. তালিকার অ্যারের পরিবর্তে তালিকার তালিকা ব্যবহার করুন:

    List< List<IntegerNode>> nodeLists = new LinkedList< List< IntegerNode >>();
  2. তালিকার অ্যারে জন্য বিশেষ শ্রেণি ঘোষণা:

    class IntegerNodeList {
        private final List< IntegerNode > nodes;
    }
    

19
পরবর্তী সমাধানের আরও ভাল বিকল্পটি class IntegerNodeList extends List<IntegerNode> {}
হ'ল

এই বাস্তবায়নটি অতিমাত্রায় ধীর। [1000] [2000] উপাদান (নোডলিস্ট.জেট (1000) .get (2000)) পাওয়া লিঙ্কডলিস্টকে 3000 বার পুনরাবৃত্তি করবে! লিঙ্কলিস্ট এড়িয়ে চলুন যদি কেউ এর সাথে ইনডেক্স করতে পারে। অ্যারেলিস্ট দ্রুত সূচক করবে, তবে ফ্রেড্রিকের সমাধান সামগ্রিকভাবে আরও ভাল।
স্টিভ জোবেল

142

কোনও কারণে আপনাকে প্রকারটি ফেলে দিতে হবে এবং ঘোষণাপত্রটি এইভাবে করতে হবে:

myMatrix = (LinkedList<IntegerNode>[]) new LinkedList<?>[numRows];

আমি একটি অনুরূপ সমস্যা নিয়ে গবেষণা করেছি এবং পড়েছি যে উপরের কাস্টটি খুব সাধারণ 'হ্যাক' যা সংগ্রহের কাঠামোর সর্বত্র ব্যবহৃত হয়।
luke করুন

15
আইএমও, এটি নির্বাচিত উত্তর হওয়া উচিত। আমি পরীক্ষা-নিরীক্ষা করিনি, তবে আমার মনে মনে অনুভব হয়েছে যে সার্জি এর # 2 পদ্ধতিটি বেশ কিছুটা ওভারহেড তৈরি করে; এবং আমি ইতিবাচক যা # 1 করে। একটি তালিকা বিভিন্ন উপায়ে অ্যারের মতো দক্ষ নয় যা আমি এখানে বিশদ করব না, তবে অ্যারের তুলনায় তালিকাগুলি ব্যবহার করার সময় আমি পরীক্ষা-নিরীক্ষা করেছি এবং বড় মন্দা দেখেছি। কোনও তালিকায় স্টাফ যুক্ত করার চেয়ে কেবল নিজের অ্যারেগুলি পরিচালনা করা এবং সেগুলি পুনরায় তালিকাভুক্ত করা দ্রুত।
রিকিট

@ রিকিট আমি সম্মত, আইবিএম
ডেভেলপ

4
আমি এখনও এটি থেকে একটি "প্রকার সুরক্ষা: চেক না করা castালাই" সতর্কতা পেয়েছি। বব এর সমাধান আমার কাছে সবচেয়ে পরিষ্কার দেখায়।
মার্কো ল্যাকোভিচ

3
জেডিকে In-তে উপরেরটি একটি কাঁচা ধরণের সতর্কতা দেয় আনবাউন্ডেড <?> টাইপ ব্যবহার করে এটি ঠিক করা যেতে পারে তবে আপনি এখনও একটি চেক না দেওয়া সতর্কতা পেয়েছেন (যা দমন করা যায়)। উদাহরণস্বরূপ <br> <কোড> মাইম্যাট্রিক্স = (লিংকডলিস্ট <IntegerNode> []) নতুন লিঙ্কডলিস্ট <?> [numRows]; </code>
নিওন

5

সিনট্যাক্সের বিষয়গুলি বাদ দিয়ে ম্যাট্রিক্স উপস্থাপনের জন্য অ্যারে এবং একটি লিঙ্কযুক্ত তালিকা ব্যবহার করা আমার কাছে অদ্ভুত বলে মনে হয়। ম্যাট্রিক্সের স্বেচ্ছাচারী কোষগুলিতে অ্যাক্সেস পাওয়ার জন্য, আপনি সম্ভবত একটি আসল অ্যারে বা কমপক্ষে একটি ArrayListসারিটি ধরে রাখতে চাইবেন , কারণ LinkedListপুরো উপাদানটি প্রথম উপাদান থেকে কোনও নির্দিষ্ট উপাদান, কোনও O(n)ক্রিয়াকলাপের মধ্যে যেতে হবে, অনেকগুলি বিপরীতে দ্রুততর O(1)সঙ্গে ArrayListঅথবা একটি প্রকৃত অ্যারের।

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

private Map<Integer, Map<Integer, IntegerNode>> myMatrix = new HashMap<Integer, Map<Integer, IntegerNode>>();

// access a matrix cell:
int rowIdx = 100;
int colIdx = 30;
Map<Integer, IntegerNode> row = myMatrix.get(rowIdx); // if null, create and add to matrix
IntegerNode node = row.get(colIdx); // possibly null

আপনি সারিতে ম্যাট্রিক্স সারি তর্ক পাবে প্রয়োজন হয়, আপনি সারি মানচিত্রে টাইপ করতে পারেন TreeMap, এবং সূচক অনুক্রমে কলাম ঢোঁড়ন জন্য একই, কিন্তু আপনি যদি সেই ক্ষেত্রে প্রয়োজন হবে না, HashMapচেয়ে দ্রুত হয় TreeMap। স্বেচ্ছাসেবক সেল পেতে এবং সেট করার জন্য সহায়ক পদ্ধতিগুলি, আনসেটটি নাল মানগুলি হ্যান্ডলিং করা অবশ্যই কার্যকর হবে।



3

myMatrix = (LinkedList<IntegerNode>[]) new LinkedList[numRows];

এইভাবে castালাই কাজ করে তবে তবুও আপনাকে একটি বাজে সতর্কতা দিয়ে চলেছে:

"সুরক্ষা প্রকারভেদ করুন: তালিকার ধরণের প্রকাশের [] অন্বেষণযোগ্য রূপান্তর প্রয়োজন .."

তালিকার অ্যারে জন্য একটি বিশেষ শ্রেণি ঘোষণা:

class IntegerNodeList { private final List< IntegerNode > nodes; }

সতর্কতা এড়ানোর জন্য একটি চতুর ধারণা। এটির জন্য একটি ইন্টারফেস ব্যবহার করা সম্ভবত কিছুটা সুন্দর:

public interface IntegerNodeList extends List<IntegerNode> {}

তারপর

List<IntegerNode>[] myMatrix = new IntegerNodeList[numRows];

সতর্কতা ছাড়াই সংকলন।

খুব খারাপ দেখাচ্ছে না, তাই না?


পূর্ণসংখ্যা নোডলিস্ট: আপনি কোন শ্রেণীর সাথে এটি ব্যবহার করবেন? উদাহরণস্বরূপ আপনি এটিকে একটি অ্যারেলিস্ট <IntegerNode> বরাদ্দ করতে পারেন নি। আপনার পাশাপাশি
অ্যারেলিস্টও

অ্যারের প্রারম্ভিকতার বাইরে ইন্টারফেস IntegerNodeList ব্যবহার করার দরকার নেই: তালিকা <IntegerNode> [] myMatrix = নতুন পূর্ণসংখ্যার নোডলিস্ট [5]; (int i = 0; i <myMatrix.length; i ++) {myMatrix [i] = নতুন অ্যারেলিস্ট <IntegerNode> (); }
ব্যবহারকারী 306708

1
List<IntegerNode>[] myMatrix = new IntegerNodeList[numRows];এটি একটি সূক্ষ্ম কিন্তু গুরুত্বপূর্ণ সমস্যা আছে। আপনি করতে পারেন শুধুমাত্র করা IntegerNodeListঅ্যারের মধ্যে। myMatrix[i] = new ArrayList<IntegerNode>();নিক্ষেপ করা হবে ArrayStoreException
রেডিওডেফ

2
List<String>[] lst = new List[2];
lst[0] = new LinkedList<String>();
lst[1] = new LinkedList<String>();

কোন সতর্কতা নেই। নেটবিন্স 6.9.1, জেডকে 1.6.0_24


1
সত্যিকারের কোনও সতর্কতা নয় তবে ওরাকলের জাভা এসই 6 আপডেট 32 সহ আমি সংকলন ত্রুটি পেয়েছি "টাইপ লিস্টটি জেনেরিক নয়; এটি <স্ট্রিং>" যুক্তি দিয়ে পরামিতি করা যায় না cannot <স্ট্রিং> আর্গুমেন্ট অপসারণ করা অন্য একটি ত্রুটি উত্পন্ন করে "টাইপ মেল্থ: লিঙ্কডলিস্ট <স্ট্রিং> থেকে তালিকায় রূপান্তর করতে পারে না"।
মার্কো ল্যাকোভিচ


0

আমি যদি নিম্নলিখিতটি করি তবে আমি ত্রুটি বার্তাটি প্রশ্নের মধ্যে পেয়েছি

LinkedList<Node>[] matrix = new LinkedList<Node>[5];

তবে আমি যদি ঘোষণাপত্রে তালিকার প্রকারটি সরিয়ে ফেলি তবে মনে হয় এটির পছন্দসই কার্যকারিতা রয়েছে।

LinkedList<Node>[] matrix = new LinkedList[5];

এই দুটি ঘোষণাগুলি কীভাবে আমি সচেতন নয় এমনভাবে আলাদা?

সম্পাদনা

আহ, আমি মনে করি আমি এখন এই সমস্যাটি নিয়ে চলেছি।

ম্যাট্রিক্সের উপর দিয়ে আইট্রেট করা এবং ফরো-লুপে তালিকাগুলি আরম্ভ করার কাজটি মনে হচ্ছে। যদিও এটি প্রস্তাবিত অন্যান্য কয়েকটি সমাধানের মতো আদর্শ নয়।

for(int i=0; i < matrix.length; i++){

    matrix[i] = new LinkedList<>();
}

0

আপনার তালিকার একটি অ্যারে দরকার, চেষ্টা করার একটি বিকল্প রয়েছে:

private IntegerNode[] node_array = new IntegerNode[sizeOfYourChoice];

তারপরে node_array[i]একটি ArrayList<IntegerNode>বা LinkedList<IntegerNode>(আপনার পছন্দের তালিকার বাস্তবায়ন যাই হোক না কেন ) এর (প্রথম) নোড সঞ্চয় করে ।

এই নকশার অধীনে, আপনি এলোমেলো অ্যাক্সেসের পদ্ধতিটি হারাতে পারেন list.get(index), তবে তারপরেও আপনি নিরাপদ অ্যারে টাইপের হেড / ফিস্ট নোড স্টোর দিয়ে শুরু করে তালিকাটি অতিক্রম করতে পারেন।

এটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে একটি গ্রহণযোগ্য নকশা পছন্দ হতে পারে। উদাহরণস্বরূপ, আমি এই নকশাটি গ্রাফের সংলগ্ন তালিকার উপস্থাপনের জন্য ব্যবহার করি, বেশিরভাগ ব্যবহারের ক্ষেত্রে, তালিকার কিছু ভার্টেক্সের পরিবর্তে এলোমেলো তালিকাটি কোনও প্রদত্ত ভার্টেক্সের পরিবর্তে প্রয়োজন হয় a

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