কীভাবে সেই মানচিত্রটিতে সন্নিবেশ আদেশের বিষয়টি যোগাযোগ করবেন?


24

আমি ডাটাবেস থেকে একটি সেট টিপল আনছি এবং একটি মানচিত্রে রাখছি। ডাটাবেস ক্যোয়ারী ব্যয়বহুল।

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

public LinkedHashMap<Key, Value> fetchData()

আমার একটি পদ্ধতি রয়েছে processDataযা মানচিত্রে কিছু প্রক্রিয়াজাতকরণ করা উচিত - কিছু মান সংশোধন করা, কিছু নতুন কী / মান যুক্ত করা। এটি হিসাবে সংজ্ঞায়িত করা হয়

public void processData(LinkedHashMap<Key, Value> data) {...}

তবে বেশ কয়েকটি লিটার (সোনার ইত্যাদি) অভিযোগ করে যে ' লিঙ্কডহ্যাশম্যাপ ' ( স্কুইড এস 1319 ) পরিবর্তে ' ডেটা'র ধরণটি ' ম্যাপ 'এর মতো একটি ইন্টারফেস হওয়া উচিত
সুতরাং মূলত এটি বলছে যে আমার থাকা উচিত

public void processData(Map<Key, Value> data) {...}

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

আমি চাই না ব্যবহার করতে চান SortedMap, কারণ এটি (থেকে এর javadocjava.util.SortedMap "অনুযায়ী আদেশ করা হয়) প্রাকৃতিক ক্রম তার কি, অথবা একটি দ্বারা comparator সাধারণত সাজানো মানচিত্র সৃষ্টি সময়ে প্রদান করা হয়েছে।"

আমার কীগুলির প্রাকৃতিক অর্ডার নেই এবং কিছুই করার জন্য তুলনামূলক তৈরি করা ভার্চুয়াল মনে হচ্ছে।

এবং আমি এখনও এটি একটি মানচিত্র হতে চাই, putসদৃশ কী ইত্যাদি এড়াতে সুবিধা গ্রহণ করা যদি তা না হয় তবে dataএকটি হতে পারত List<Map.Entry<Key, Value>>

সুতরাং আমি কীভাবে বলব যে আমার পদ্ধতিটি এমন একটি মানচিত্র চায় যা ইতিমধ্যে সাজানো হয়েছে ? দুঃখের বিষয়, কোনও java.util.LinkedMapইন্টারফেস নেই, বা আমি এটি ব্যবহার করতাম।

উত্তর:


56

সুতরাং ব্যবহার LinkedHashMap

হ্যাঁ , Mapযখনই সম্ভব আপনার একটি নির্দিষ্ট প্রয়োগকরণ ব্যবহার করা উচিত এবং হ্যাঁ , এটি সর্বোত্তম অনুশীলন।

এটি বলেছিল, এটি একটি অদ্ভুতভাবে নির্দিষ্ট পরিস্থিতি যেখানে বাস্তবায়নের বিষয়টি Mapবাস্তবে গুরুত্বপূর্ণ actually আপনি যখন ব্যবহার করবেন তখন আপনার কোডের 99.9% ক্ষেত্রে এটি সত্য হবে না Mapএবং এখনও আপনি এই 0.1% অবস্থায় রয়েছেন । সোনার এটি জানতে পারে না এবং তাই সোনার আপনাকে সুনির্দিষ্টভাবে প্রয়োগটি এড়াতে বলে দেয় কারণ এটি বেশিরভাগ ক্ষেত্রেই সঠিক হবে।

আমি যুক্তি দিয়ে বলব যে আপনি যদি একটি নির্দিষ্ট বাস্তবায়ন ব্যবহারের জন্য কেস করতে পারেন তবে শূকরকে লিপস্টিক লাগানোর চেষ্টা করবেন না। আপনার দরকার একটি LinkedHashMap, একটি নয় Map

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


1
বাস্তববাদী পদ্ধতির, যা আমি পছন্দ করি।
বিদার এস রামদল

20
আমি উত্তর সঙ্গে প্রায় সম্পূর্ণ সম্মত। আমি শুধু বলব যে আপনি সোনার জন্য জালিয়াতি করা হয় না। নির্দিষ্ট ত্রুটি / সতর্কতা উপেক্ষা করার জন্য আপনি সর্বদা এটি কনফিগার করতে পারেন। দেখুন stackoverflow.com/questions/10971968/...
ভ্লাদিমির Stokic

11
if you are new to programming and stumble upon this answer, don't think this allows you to go against best practice because it doesn't.- ভাল পরামর্শ, যদি "সর্বোত্তম অনুশীলন" বলে কিছু থাকে। আরও ভাল পরামর্শ: কীভাবে সঠিক সিদ্ধান্ত নিতে হয় তা শিখুন। অনুশীলনটি যদি তা বোঝা যায় তবে তা অনুসরণ করুন, তবে সরঞ্জাম এবং কর্তৃপক্ষকে আপনার চিন্তাভাবনা প্রক্রিয়ায় গাইড করুন, এটি নির্দেশ না করুন।
রবার্ট হার্ভে

13
দ্রষ্টব্য: সোনার যখন আপনাকে কিছু জানায়, আপনি এটিকে "সমাধান করবেন না" হিসাবে বন্ধ করতে পারেন এবং আপনি কেন করবেন না সে হিসাবে একটি নোট রেখে যেতে পারেন। যেমন সোনার কেবল আপনাকে বিরক্ত করতেই থামবে না, তবে আপনি কেন এটি করেছিলেন তার একটি ট্রেসার পাবেন।
ওয়ালফ্র্যাট

2
আমি মনে করি যে দিকটি এটি সাধারণ নীতিটির ব্যতিক্রম করে তোলে তা হ'ল লিংকডহ্যাশম্যাপের একটি চুক্তি রয়েছে যা সেই বাস্তবায়নের জন্য নির্দিষ্ট এবং কোনও ইন্টারফেসে প্রকাশিত হয় না। এটি সাধারণ ঘটনা নয়। সুতরাং সেই চুক্তির উপর নির্ভরতা প্রকাশের একমাত্র উপায় হ'ল বাস্তবায়ন ধরণের ব্যবহার।
দানা

21

আপনি তিনটি জিনিস লড়াই করছেন:

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

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

তৃতীয়, এবং এটি সম্ভবত এটির মাংস, এটি LinkedHashMapকাজের জন্য ভুল সরঞ্জাম হতে পারে। মানচিত্রগুলি এলোমেলোভাবে নির্দেশিত, অ্যাক্সেসের আদেশের জন্য নয়। যদি processData()সহজভাবে রেকর্ডগুলির উপর পুনরাবৃত্তি হয় এবং কী দ্বারা অন্য রেকর্ডগুলি সন্ধানের প্রয়োজন না হয়, আপনি Mapএ এর কাজটি করার জন্য একটি নির্দিষ্ট প্রয়োগের জন্য বাধ্য করছেন List। অন্যদিকে, যদি আপনার উভয়ের প্রয়োজন LinkedHashMapহয় তবে এটি সঠিক সরঞ্জাম কারণ এটি আপনার যা করতে চান তা জানা যায় এবং আপনি এটির প্রয়োজনের তুলনায় ন্যায়সঙ্গত।


2
"লিঙ্কডহ্যাশম্যাপটি কাজের জন্য ভুল সরঞ্জাম হতে পারে"। হ্যা সম্ভবত. যখন আমি বলি আমার একটি দরকারOrderedMap , আমি শুধু পাশাপাশি বলতে পারে UniqueList। যতক্ষণ না এটি সংজ্ঞায়িত পুনরাবৃত্তির ক্রম সহ কোনও প্রকারের সংগ্রহ থাকে, এটি সন্নিবেশ করায় ডুপ্লিকেটগুলি ওভাররাইট করে।
বিদার এস রামদল

2
@ VidarS.Ramdal ডাটাবেস ক্যোয়ারী হ'ল নকল ছাঁটাই করার আদর্শ জায়গা। যদি আপনার ডাটাবেস এটি না করতে পারে Setতবে আপনি তালিকাটি তৈরি করার সময় আপনি কেবল কীগুলির অস্থায়ী রাখতে পারেন ।
ব্লারফ্ল

ওহ, আমি দেখি আমি বিভ্রান্তি সৃষ্টি করেছি। হ্যাঁ, ডাটাবেস ক্যোয়ারী ফলাফলের সদৃশ থাকে না। তবে processDataকিছু মান পরিবর্তিত করে কিছু নতুন কী / মান প্রবর্তন করে মানচিত্রটি পরিবর্তন করে। সুতরাং processDataএটি অনুলিপি প্রবর্তন করতে পারে যদি এটি একটি ছাড়া অন্য কিছুতে কাজ করে Map
ভিদার এস রামদল

7
@ ভিডারস.রামডাল: মনে হচ্ছে আপনার নিজের UniqueList(বা OrderedUniqueList) লিখতে হবে এবং এটি ব্যবহার করা উচিত। এটি বেশ সহজ, এবং আপনার উদ্দেশ্য ব্যবহারকে আরও পরিষ্কার করে তোলে।
টিএমএন

2
@ টিএমএন হ্যাঁ, আমি সেদিকেই ভাবতে শুরু করেছি। যদি আপনি উত্তর হিসাবে আপনার পরামর্শ পোস্ট করতে চান, এটি অবশ্যই আমার উর্ধ্বে পাবে।
ভিদার এস রামদল

15

যদি আপনি যা কিছু পেয়ে যাচ্ছেন LinkedHashMapতা হ'ল ডুপ্লিকেটগুলি ওভাররাইট করার ক্ষমতা, তবে আপনি সত্যিই এটি হিসাবে ব্যবহার করছেন List, তবে আমি নিজের কাস্টম Listবাস্তবায়নের মাধ্যমে সেই ব্যবহারটি যোগাযোগ করার চেয়ে ভাল পরামর্শ দিচ্ছি । আপনি এটি একটি বিদ্যমান জাভা সংগ্রহের ক্লাসে ভিত্তি করতে পারেন addএবং removeআপনার ব্যাকিং স্টোরটি আপডেট করার জন্য কোনও উপায় এবং পদ্ধতি ওভাররাইড করতে পারেন এবং স্বতন্ত্রতা নিশ্চিত করার জন্য কীটির ট্র্যাক রাখতে পারেন। এর মতো একটি স্বতন্ত্র নাম দেওয়া ProcessingListএটি পরিষ্কার করে দেবে যে আপনার processDataপদ্ধতিতে উপস্থাপন করা যুক্তিগুলি একটি বিশেষ উপায়ে পরিচালনা করা দরকার।


5
এটি যাইহোক ভাল ধারণা হতে পারে। হেক, আপনার এমনকি একটি লাইন ফাইল থাকতে পারে যা ProcessingListএকটি উপাধি হিসাবে তৈরি করে LinkedHashMap- আপনি যতক্ষণ না সর্বজনীন ইন্টারফেস অক্ষত রাখেন ততক্ষণ আপনি পরে অন্য কোনও কিছু দিয়ে প্রতিস্থাপন করার সিদ্ধান্ত নিতে পারেন।
কম্পিউশিপ

11

আমি শুনছি আপনি বলছেন "আমার কাছে আমার সিস্টেমের একটি অংশ রয়েছে যা একটি লিঙ্কডহ্যাশম্যাপ তৈরি করে এবং আমার সিস্টেমের অন্য একটি অংশে আমাকে কেবল লিংকডহ্যাশম্যাপ অবজেক্ট গ্রহণ করতে হবে যেগুলি প্রথম অংশ দ্বারা উত্পাদিত হয়েছিল, যেহেতু অন্য কোনও প্রক্রিয়া দ্বারা উত্পাদিত জিনিসগুলি জিতেছে ' টি সঠিকভাবে কাজ করে না। "

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

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

আপনার যদি দুটি ভেরিয়েবল থাকে যেগুলি আপনাকে এই জাতীয় চারপাশে অতিক্রম করার দরকার ছিল, আপনি সম্ভবত এটি সম্পর্কে খুব বেশি চিন্তা না করেই এটির জন্য একটি ক্লাস তৈরি করতে চাইতেন। তবে কখনও কখনও এটি কেবলমাত্র এক সদস্যের পরিবর্তনশীল হলেও একটি শ্রেণি রাখা কার্যকর, কারণ এটি যৌক্তিকভাবে একই জিনিস, "মান" নয়, "আমার অপারেশনের ফলাফল যা আমাকে পরবর্তীকালে জিনিসগুলি করা দরকার"।


আমি এই চিন্তা মত - আমি সেখানে ছিলাম :) MyBagOfUsefulInformationএকটি পদ্ধতি (অথবা কন্সট্রাকটর) এটিকে পূরণ করতে হবে: MyBagOfUsefulInformation.populate(SomeType data)। তবে dataসাজানো ক্যোয়ারির ফলাফল হওয়া দরকার। তাহলে কী হবে SomeType, যদি না হয় LinkedHashMap? আমি নিশ্চিত নই যে আমি এই ক্যাচটি 22 টি ভাঙ্গতে পেরেছি
ভিদার এস রামদল

MyBagOfUsefulInformationডিএও বা আপনার সিস্টেমে যা কিছু ডেটা তৈরি করছে তা কেন তৈরি করা যায় না? ব্যাগের উত্পাদক এবং গ্রাহকের বাইরে আপনার কোডের বাকি অংশে কেন অন্তর্নিহিত মানচিত্রটি প্রকাশ করতে হবে?

আপনার আর্কিটেকচারের উপর নির্ভর করে, আপনি কেবল প্রাইভেট / সুরক্ষিত / প্যাকেজ-কেবল নির্মাণকারী ব্যবহার করতে সক্ষম হবেন যা কেবলমাত্র এটির প্রযোজকই তৈরি করতে পারবেন যা কেবল আপনি চান want বা আপনার এটি কেবল একটি সম্মেলন হিসাবে করার দরকার হতে পারে, এটি কেবলমাত্র "কারখানা" দ্বারা তৈরি করা যেতে পারে।

হ্যাঁ, আমি MyBagOfUsefulInformationডিএও পদ্ধতিতে প্যারামিটার হিসাবে পাস করে কিছুটা অনুরূপ কিছু করতে
পেরেছি

4

লিংকডহ্যাশম্যাপটি কেবলমাত্র জাভা মানচিত্র যা সন্ধানের জন্য সন্নিবেশ ক্রমের বৈশিষ্ট্য রয়েছে। সুতরাং নির্ভরতা বিপরীতমুখী নীতি ত্যাগ করা লোভনীয় এবং সম্ভবত বাস্তবসম্মত। প্রথমে, এটি অনুসরণ করতে কী গ্রহণ করবে তা বিবেচনা করুন। সলিড আপনাকে যা করতে বলবে তা এখানে ।

দ্রষ্টব্য: Ramdalএকটি বর্ণনামূলক নাম দিয়ে নামটি প্রতিস্থাপন করুন যা যোগাযোগ করে যে এই ইন্টারফেসের গ্রাহক এই ইন্টারফেসের মালিক। সন্নিবেশনের আদেশটি গুরুত্বপূর্ণ কিনা তা সিদ্ধান্ত নিয়েছে এমন এটি কর্তৃপক্ষকে তোলে। আপনি যদি এটিকে কল করেন তবে InsertionOrderMapআপনি সত্যিই বিষয়টিটি মিস করেছেন।

public interface Ramdal {
    //ISP asks for just the methods that processData() actually uses.
    ...
}

public class RamdalLinkedHashMap extends LinkedHashMap implements Ramdal{} 

Ramdal<Key, Value> ramdal = new RamdalLinkedHashMap<>();

ramdal.put(key1, value1);
ramdal.put(key2, value2);

processData(ramdal);

এটি কি সামনে বড় নকশা? হতে পারে, আপনি কতটা সম্ভবত ভাবেন তার উপর নির্ভর করে যে আপনার পাশাপাশি কখনও বাস্তবায়ন প্রয়োজন LinkedHashMap। তবে আপনি যদি ডিআইপি অনুসরণ না করেন তবে এটি ব্যথার বড় ব্যথা হবে বলে আমি মনে করি না যে বয়লার প্লেট এর চেয়ে আর কোনও বেদনাদায়ক is আমি যখন অস্পৃশ্য কোডটি এমন একটি ইন্টারফেস প্রয়োগ করি যা এটি ব্যবহার করে না তখন আমি এটি ব্যবহার করি। সবচেয়ে বেদনাদায়ক অংশটি আসলে ভাল নাম নিয়ে ভাবছে।


2
আমি নামকরণ পছন্দ করি!
বিদার এস রামদল

1

প্রচুর ভাল পরামর্শ এবং চিন্তার জন্য খাবারের জন্য ধন্যবাদ।

আমি processDataএকটি উদাহরণের পদ্ধতি তৈরি করে একটি নতুন মানচিত্রের ক্লাস তৈরি করে শেষ করেছি :

class DataMap extends LinkedHashMap<Key, Value> {

   processData();

}

তারপরে আমি ডিএও পদ্ধতিটি রিফ্যাক্ট করেছিলাম যাতে এটি কোনও মানচিত্র ফেরত না দেয়, পরিবর্তে একটি targetমানচিত্রকে প্যারামিটার হিসাবে নেয় :

public void fetchData(Map<Key, Value> target) {
  ...
  // for each result row
  target.put(key, value);
}

সুতরাং জনসংখ্যা স্থাপন DataMapএবং ডেটা প্রক্রিয়াকরণ এখন একটি দ্বি-পদক্ষেপ প্রক্রিয়া, যা ঠিক আছে, যেহেতু অন্যান্য কিছু ভেরিয়েবল রয়েছে যা অ্যালগোরিদমের অংশ, যা অন্য জায়গা থেকে আসে।

public DataMap fetchDataMap() {
  var dataMap = new DataMap();
  dao.fetchData(dataMap);
  return dataMap;
}

এটি আমার মানচিত্র বাস্তবায়নের মাধ্যমে কীভাবে এন্ট্রি প্রবেশ করানো হয় তা নিয়ন্ত্রণ করতে এবং আদেশের প্রয়োজনীয়তাটি গোপন করে - এটি এখন একটি বাস্তবায়ন বিশদ DataMap


0

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

সতর্কতা দমন করা আমার মতে মন্তব্য করার চেয়ে নিকৃষ্ট, কারণ দমন নিজেই সতর্কতাটি চাপা দেওয়ার কারণটি উল্লেখ করে না। সতর্কতা দমন ও মন্তব্যের সংমিশ্রণটিও ঠিক থাকবে।


0

সুতরাং, আমাকে এখানে আপনার প্রসঙ্গটি বোঝার চেষ্টা করুন:

... সন্নিবেশ আদেশের বিষয়টি ... মানচিত্রটিকে বাছাই করা একটি ভারী ক্রিয়াকলাপ হবে ...

... ক্যোয়ারী ফলাফলটি আমি এটি চাইলে আগেই সাজানো হয়েছে

এখন, আপনি বর্তমানে ইতিমধ্যে যা করছেন:

আমি ডাটাবেস থেকে একটি টিপল সংগ্রহ করছি এবং এটিকে একটি মানচিত্রে রাখছি ...

এবং আপনার বর্তমান কোড এখানে:

public void processData(LinkedHashMap<Key, Value> data) {...}

আমার পরামর্শটি নিম্নলিখিতটি করা:

  • নির্ভরতা ইনজেকশন ব্যবহার করুন এবং প্রসেসিং পদ্ধতিতে কিছু MyTupleRepository ইনজেকশন করুন (MyTupleRepository এমন একটি ইন্টারফেস যা আপনার টুপল অবজেক্টগুলি সাধারণত ডিবি থেকে পুনরুদ্ধার করে এমন বস্তু দ্বারা প্রয়োগ করা হয়);
  • অভ্যন্তরীণভাবে প্রক্রিয়াজাতকরণের পদ্ধতিতে, নির্দিষ্ট লিঙ্কডহ্যাশম্যাপ সংগ্রহের সংগ্রহস্থল (ওরফে ডিবি, যা ইতিমধ্যে অর্ডার করা ডেটা ফেরত দেয়) থেকে ডেটা রাখুন কারণ এটি প্রক্রিয়াজাতকরণ অ্যালগরিদমের অভ্যন্তরীণ বিবরণ (কারণ এটি কীভাবে ডেটা কাঠামোয় ডেটা সাজানো হয়েছে তার উপর নির্ভর করে );
  • মনে রাখবেন, আপনি ইতিমধ্যে যা করছেন এটি এটি বেশ কিছু, তবে এই ক্ষেত্রে এটি প্রক্রিয়াজাতকরণ পদ্ধতির মধ্যেই করা হবে। আপনার সংগ্রহস্থলটি অন্য কোথাও ইনস্ট্যান্ট করা হয়েছে (আপনার ইতিমধ্যে একটি ক্লাস রয়েছে যা ডেটা ফেরত দেয়, এটি এই উদাহরণের ভাণ্ডার)

কোড উদাহরণ

public interface MyTupleRepository {
    Collection<MyTuple> GetAll();
}

//Concrete implementation of data access object, that retrieves 
//your tuples from DB; this data is already ordered by the query
public class DbMyTupleRepository implements MyTupleRepository { }

//Injects some abstraction of repository into the processing method,
//but make it clear that some exception might be thrown if data is not
//arranged in some specific way you need
public void processData(MyTupleRepository tupleRepo) throws DataNotOrderedException {

    LinkedHashMap<Key, Value> data = new LinkedHashMap<Key, Value>();

    //Represents the query to DB, that already returns ordered data
    Collection<MyTuple> myTuples = tupleRepo.GetAll();

    //Optional: this would throw some exception if data is not ordered 
    Validate(myTuples);

    for (MyTupleData t : myTuples) {
        data.put(t.key, t.value);
    }

    //Perform the processing using LinkedHashMap...
    ...
}

আমার ধারণা, এটি সোনার সতর্কতা থেকে মুক্তি পাবে এবং প্রসেসিং পদ্ধতির দ্বারা প্রয়োজনীয় ডেটার স্বাক্ষর নির্দিষ্ট বিন্যাসেও নির্দিষ্ট করে দেবে।


হুঁ, তবে কীভাবে তা ইনস্ট্যান্টেট করা হবে? এটি কি সমস্যাটিকে অন্য কোথাও স্থানান্তরিত করবে না (কোথায় MyTupleRepositoryতৈরি করা হয়েছে?)
বিদার এস রামদল

আমি মনে করি আমি পিটার কুপারের উত্তরের মতোই একই সমস্যার মুখোমুখি হব ।
ভিদার এস রামদল

আমার পরামর্শ নির্ভরতা ইনজেকশন নীতি প্রয়োগ জড়িত; এই উদাহরণে; MyTupleRepository একটি ইন্টারফেস যা আপনার উল্লিখিত টিপলগুলি পুনরুদ্ধার করার ক্ষমতা নির্ধারণ করে (যা ডিবি কে জিজ্ঞাসা করে)। এখানে, আপনি প্রক্রিয়া পদ্ধতিতে এই বস্তুকে ইনজেক্ট করুন। আপনার ইতিমধ্যে কিছু শ্রেণি রয়েছে যা ডেটা ফেরত দেয়; এটি কেবলমাত্র একটি ইন্টারফেসে এটি বিমূর্ত করে তোলে এবং আপনি 'প্রসেসডেটা' পদ্ধতিতে অবজেক্টটি ইনজেক্ট করেন যা অভ্যন্তরীণভাবে লিঙ্কডহ্যাশম্যাপ ব্যবহার করে কারণ এটি অভ্যন্তরীণভাবে প্রক্রিয়াজাতকরণের অংশ part
এমারসন কার্ডোসো

আমি আমার উত্তরটি সম্পাদনা করেছি, আমি কী পরামর্শ দিচ্ছি তা সম্পর্কে আরও পরিষ্কার হওয়ার চেষ্টা করে।
এমারসন কার্ডোসো

-1

এই প্রশ্নটি আসলে আপনার ডেটা মডেলটিকে একের মধ্যে নিয়ে আসে এমন একগুচ্ছ বিষয়। আপনার একবারে একবারে সেগুলি বন্ধন করা শুরু করা উচিত। আপনি ধাঁধাটির প্রতিটি টুকরো সহজ করার চেষ্টা করার সাথে আরও প্রাকৃতিক, স্বজ্ঞাত সমাধানগুলি নেমে আসবে।

সমস্যা 1: আপনি ডিবি অর্ডারের উপর নির্ভর করতে পারবেন না

আপনার ডেটা বাছাই করার বিবরণগুলি পরিষ্কার নয়।

  • সর্বাধিক সম্ভাব্য সমস্যাটি হ'ল আপনি কোনও ORDER BYক্লজের মাধ্যমে আপনার ডাটাবেসে একটি স্পষ্ট বাছাই নির্দিষ্ট করছেন না । যদি আপনি এটি ব্যয়বহুল বলে মনে করেন না, তবে আপনার প্রোগ্রামটিতে একটি বাগ রয়েছে । ডাটাবেসগুলিকে কোনও আদেশে ফলাফল ফেরত দেওয়ার অনুমতি দেওয়া হয় যদি আপনি একটি নির্দিষ্ট করে না থাকেন; আপনি এর উপর নির্ভর করতে পারবেন না কাকতালীয়ভাবে ক্রমে ডেটা ফিরিয়ে দেওয়ার কারণে আপনি কয়েকবার ক্যোয়ারী চালিয়েছেন এবং এটি সেভাবে দেখায়। অর্ডার পরিবর্তন হতে পারে কারণ সারিগুলি ডিস্কে পুনরায় সাজানো হয়, বা কিছু মুছে ফেলা হয় এবং নতুন তাদের স্থান নেয় বা একটি সূচক যুক্ত হয়। আপনাকে অবশ্যইORDER BY কোনও ধরণের একটি ধারা উল্লেখ করতে হবে । গতি নির্ভুলতা ছাড়া মূল্যহীন।
  • সন্নিবেশ আদেশের বিষয়টি দ্বারা আপনি কী বোঝাতে চাইছেন তাও পরিষ্কার নয়। আপনি নিজেই ডাটাবেস সম্পর্কে কথা বলছেন, আপনি অবশ্যই একটি কলাম থাকতে হবে যা এটি সত্যই ট্র্যাক করবে এবং এটি অবশ্যই আপনার ORDER BYধারাতে অন্তর্ভুক্ত করা উচিত । অন্যথায়, আপনি বাগ আছে। যদি এই জাতীয় কলামটি এখনও বিদ্যমান না থাকে, তবে আপনাকে একটি যুক্ত করতে হবে। এটির মতো কলামগুলির জন্য সাধারণ বিকল্পগুলি একটি সন্নিবেশ টাইমস্ট্যাম্প কলাম বা একটি স্বয়ং-বৃদ্ধিকরণ কী হবে। স্বতঃবৃদ্ধি কী আরও নির্ভরযোগ্য।

সমস্যা 2: মেমরি সাজানোর দক্ষ করে তোলা

একবার আপনি নিশ্চিত করুন যে এটি এর নিশ্চয়তা প্রকারের অর্ডার আশা, আপনি মেমরি করতে এই সত্য লিভারেজ করতে পারেন তথ্য ফেরার করা অনেক আরও দক্ষ। শুধু একটি বা যোগ করুনrow_number()dense_rank()আপনার প্রশ্নের ফলাফলের সেটটিতে কলাম (বা আপনার ডাটাবেসের সমতুল্য) যুক্ত করুন। এখন প্রতিটি সারিতে একটি সূচক রয়েছে যা আপনাকে অর্ডার হওয়ার কথা বলে এর সরাসরি ইঙ্গিত দেবে এবং আপনি এটিকে মেমরির সাথে তুচ্ছভাবে বাছাই করতে পারেন। কেবলমাত্র নিশ্চিত হয়ে নিন যে আপনি সূচকে একটি অর্থপূর্ণ নাম দিয়েছেন (যেমন sortedBySomethingIndex)।

ভায়োলা। এখন আপনাকে আর ডাটাবেস ফলাফল সেট আদেশ উপর নির্ভর করতে হবে না।

সমস্যা 3: আপনি কি কোডে এই প্রক্রিয়াজাতকরণ করার প্রয়োজন?

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

আপনি এমনকি না প্রয়োজন ভালো মেমরিতে আপনার ডেটা টান কিভাবে? অথবা উইন্ডো ফাংশন ব্যবহার করে আপনি এসকিউএল কোয়েরিতে সমস্ত কাজ করতে পারেন? আপনি যদি ডিবিতে সমস্ত কাজ (বা সম্ভবত এমনকি একটি উল্লেখযোগ্য অংশ) করতে পারেন, দুর্দান্ত! আপনার কোড সমস্যা চলে যায় (বা অনেক সহজ হয়ে যায়)!

সমস্যা 4: আপনি এটি কি করছেন data?

ধরে নিচ্ছি আপনি ডিবিতে এটি সবই করতে পারবেন না, আমাকে এই সোজা করে দেওয়া যাক। আপনি মানচিত্র হিসাবে ডেটা নিচ্ছেন (যা আপনি সাজানোর জন্য চান না এমন জিনিস দ্বারা কীড করা হয়), তারপরে আপনি এটি সন্নিবেশ ক্রমে পুনরাবৃত্তি করছেন এবং কিছু কীগুলির মান প্রতিস্থাপন করে এবং মানচিত্রটি পরিবর্তিত করে সংযোজন করে যোগ করছেন নতুন একটি?

আমি দুঃখিত, কিন্তু হেক কি?

কলকারীদের এই সমস্ত সম্পর্কে চিন্তা করা উচিত নয় । আপনার তৈরি করা সিস্টেমটি অত্যন্ত নাজুক। কিছুটা ভুল পরিবর্তন করার জন্য এটি কেবল একটি বোবা ভুল করতে পারে (এমনকি নিজের দ্বারা তৈরিও করা হয়েছে, যেমন আমরা সবাই করেছি) এবং পুরো জিনিসটি কার্ডের ডেকের মতো ধসে যায়।

এখানে সম্ভবত আরও ভাল ধারণা:

  • আপনার ফাংশন একটি গ্রহণ করতে List
  • অর্ডার করার সমস্যাটি আপনি পরিচালনা করতে পারেন এমন কয়েকটি উপায় রয়েছে।
    1. ব্যর্থ দ্রুত প্রয়োগ করুন। তালিকার ক্রমটি ক্রমের প্রয়োজন অনুসারে না থাকলে একটি ত্রুটি নিক্ষেপ করুন। (দ্রষ্টব্য: আপনি সমস্যা 2 থেকে বাছাই সূচকটি এটি কিনা তা জানাতে পারেন))
    2. নিজেকে বাছাই করা অনুলিপি তৈরি করুন (আবার সমস্যা 2 থেকে সূচকটি ব্যবহার করুন)।
    3. যাতে মানচিত্রটি নিজেই ক্রমানুসারে তৈরি করার উপায় খুঁজে বের করুন।
  • অভ্যন্তরীণভাবে ফাংশনে আপনার প্রয়োজনীয় মানচিত্রটি তৈরি করুন, যাতে কলারটিকে এটির যত্ন নেওয়ার দরকার নেই।
  • আপনার কাছে অর্ডার উপস্থাপনায় যাই হোক না কেন তার পুনরাবৃত্তি করুন এবং আপনার যা করতে হবে তা করুন।
  • মানচিত্রটি ফিরিয়ে দিন, বা এটিকে একটি উপযুক্ত ফেরতের মান হিসাবে রূপান্তর করুন

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

বা হতে পারে এটি আরও অর্থবোধ করে: dataপ্যারামিটারটি থেকে মুক্তি পান এবং processDataআসলে তার নিজস্ব ডেটা আনুন fet তারপরে আপনি নথিটি তৈরি করতে পারেন যে আপনি এটি করছেন কারণ এতে ডেটা আনার পথে খুব নির্দিষ্ট প্রয়োজনীয়তা রয়েছে। অন্য কথায়, ফাংশনটি নিজস্ব করুন কেবলমাত্র এক টুকরো নয়, পুরো প্রক্রিয়াটির করুন; আন্ত-নির্ভরতা খুব যুক্তিযুক্ত যুক্তিটিকে ছোট অংশগুলিতে বিভক্ত করতে। (প্রক্রিয়াটির ফাংশনের নাম পরিবর্তন করুন))

সম্ভবত এটি আপনার পরিস্থিতির জন্য কাজ করবে না। আমি সমস্যার পুরো বিবরণ ছাড়া জানি না। আমি যখন শুনি তবে আমি একটি নাজুক এবং বিভ্রান্তিকর নকশা জানি।

সারাংশ

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

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


"আপনার কী বোঝাতে চাইছেন যে কোনও প্রাকৃতিক অর্ডার নেই তবে সন্নিবেশ আদেশের বিষয়টি বিবেচনা করে? আপনি কি বলছেন যে ডিবি টেবিলে ডেটা orderোকানো হয়েছিল তা বিবেচ্য, তবে আপনার কোনও কলাম নেই যা আপনাকে কী অর্ডার orderোকানো হয়েছিল তা বলতে পারে না?" - প্রশ্নটি এটিকে বলে: "মানচিত্রের বাছাই করা একটি ভারী ক্রিয়াকলাপ হবে, সুতরাং ক্যোয়ারির ফলাফলটি ইতিমধ্যে বাছাই করা হয়ে গিয়ে আমি তা করা এড়াতে চাই"। এর পরিষ্কার অর্থ হ'ল ডেটাতে একটি গণনযোগ্য নির্দিষ্ট আদেশ রয়েছে, কারণ অন্যথায় এটি বাছাই করা ভারী না হয়ে অসম্ভব, তবে এই সংজ্ঞায়িত ক্রমটি কীগুলির প্রাকৃতিক ক্রমের চেয়ে পৃথক।
জুলস

2
অন্য কথায়, ওপি একটি ক্যোয়ারির ফলাফলের মতো কাজ করছে select key, value from table where ... order by othercolumnএবং তাদের প্রসেসিংয়ে ক্রম বজায় রাখা দরকার। সন্নিবেশ অর্ডার তারা উল্লেখ করছি তাদের মানচিত্রে সন্নিবেশ অর্ডার , তাদের ক্যোয়ারী, না ব্যবহৃত আদেশ দ্বারা সংজ্ঞায়িত ডাটাবেসের মধ্যে সন্নিবেশ অর্ডার । এটি তাদের ব্যবহারের মাধ্যমে স্পষ্ট হয়ে উঠেছে LinkedHashMap, যা এমন একটি ডেটা স্ট্রাকচার যা কী Mapএবং Listমান মূল্যের জোড়া উভয়ের বৈশিষ্ট্য ধারণ করে।
জুলাইস

@ জুলস আমি এই বিভাগটি কিছুটা পরিষ্কার করব, ধন্যবাদ। (আমি আসলে এটি পড়ে মনে পড়েছিলাম, তবে আমি যখন প্রশ্নটি লেখার সময় জিনিসগুলি যাচাই করছিলাম তখন আমি এটি খুঁজে পেলাম না ol লোল। আগাছায়ও পেয়ে গেলাম)) তবে ডিবি দিয়ে তারা কী করছে তা নিয়ে প্রশ্ন পরিষ্কার হয়নি isn't ক্যোয়ারী এবং তাদের একটি সুস্পষ্ট বাছাই আছে কিনা তারা আরও বলে যে "সন্নিবেশনের আদেশের বিষয়টি গুরুত্বপূর্ণ।" মুল বক্তব্যটি হ'ল বাছাই করা ভারী হলেও, আপনি স্পষ্টভাবে কিছু না বললে আপনি কেবল যাদুকরভাবে জিনিসগুলি সঠিকভাবে অর্ডার করতে ডিবি-র উপর নির্ভর করতে পারবেন না। এবং যদি আপনি হয় ডিবি এটা করছেন, তাহলে আপনি একটি "সূচক" এটা কোডে কার্যকর করা ব্যবহার করতে পারেন।
jpmc26

* উত্তর লিখছেন (শিথিল শিথিল হওয়া উচিত
পদ্ধতিগুলি

হ্যাঁ, @ জুলাইস ঠিক আছে। সেখানে হয় একটি order byক্যোয়ারীতে দফা, কিন্তু এটা অ তুচ্ছ (হয় না শুধু order by column,) তাই আমি জাভা বাছাই reimplementing এড়াতে চান। যদিও এসকিউএল হয় শক্তিশালী (এবং আমরা একটি ওরাকল 11g ডাটাবেসের সম্পর্কে এখানে কথা বলছি), প্রকৃতি processDataঅ্যালগরিদম এটা অনেক সহজ জাভা প্রকাশ করে তোলে। এবং হ্যাঁ, "সন্নিবেশ আদেশ" এর অর্থ " মানচিত্র সন্নিবেশ আদেশ", অর্থাত্ কোয়েরি ফলাফলের ক্রম।
ভিদার এস রামদল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.