জাভা: সংগ্রহ থেকে প্রথম আইটেমটি পান


277

আমার যদি কোনও সংগ্রহ থাকে, যেমন Collection<String> strs, আমি কীভাবে প্রথম জিনিসটি বের করতে পারি? আমি কেবল একটি কল করতে পারি Iterator, এটি প্রথম নিতে next(), তারপরে Iteratorদূরে ফেলে দিতে পারি। এটি করার কোনও কম অপচয় করার উপায় কী?


1
অবশ্যই আপনি যদি প্রয়োগকারী ধারক শ্রেণিটি জানেন তবে প্রথম উপাদানটি অ্যাক্সেস করার আরও ভাল উপায় হতে পারে ...
রুক

কোনো সূচির জন্য সাধারণীকরণ: stackoverflow.com/questions/1047957/...
সিরো Santilli郝海东冠状病六四事件法轮功

1
দেখে মনে হচ্ছে আপনার Queue.peek () দরকার
জোহানেস

উত্তর:


131

Iterables.get (আপনার সি, সূচক ইউয়ান্ট)

কারণ সত্যই, আপনি যদি সংগ্রহগুলি ব্যবহার করছেন তবে আপনার Google সংগ্রহগুলি ব্যবহার করা উচিত।


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

1
সত্যই, পারফরম্যান্স-ভিত্তিতে এটি সি.এরেটর () পরবর্তী () এর চেয়ে সামান্য ধীর হতে পারে - তবে কোডটি আরও পরিস্কার এবং সংশোধন করা সহজ simp
কার্ল

2
আমি অবশ্যই এটি পরিষ্কার হিসাবে সম্মত, কিন্তু ওপি অপব্যয় সম্পর্কে ছিল, তবে আমি অনুমান করি যেহেতু আপনার উত্তরটি গৃহীত হয়েছিল এটিই পছন্দসই ছিল।
যিশাই

8
যারা (এখনও) এখানে পৌঁছেছেন তাদের জন্য: আমি মনে করি যে জেডিডিংসের উত্তর সম্ভবত সবচেয়ে ভাল "এটি সম্পন্ন করুন" উত্তর, যদিও আমি ইতিমধ্যে জিসি লাইব্রেরি ব্যবহার করছি এমন ক্ষেত্রে আমি @ ডোনাল্ডআরবকে (পৃষ্ঠাতে নামার) পছন্দ করতাম। আমার উত্তরটি সত্যিই সেই ক্ষেত্রে যেখানে কেউ পরে নমনীয়তায় লিখতে চাইতে পারে (বলুন, যদি কেউ সিদ্ধান্ত নেয় যে দ্বিতীয় উপাদানটি নতুন হটনেস হয়) is
কার্ল

4
কখনও কখনও আপনি কেবল কোডগুলি ব্যবহার করেন যা সংগ্রহগুলি ব্যবহার করে, তাই করার মতো খুব বেশি কিছু নেই।
এরিক্র্ফ

436

দেখে মনে হচ্ছে এটি করার সর্বোত্তম উপায়:

String first = strs.iterator().next();

দুর্দান্ত প্রশ্ন ... প্রথমে এটি মনে হয় একটি পর্যবেক্ষণের মতো Collection ইন্টারফেসের ।

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

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

উদাহরণস্বরূপ, ArrayList<String>.iterator()পদ্ধতিটি দ্বারা প্রত্যাবর্তিত প্রকারের দিকে তাকালে আমরা দেখতে পাই যে এটি isArrayList::Itr । এটি একটি অভ্যন্তরীণ শ্রেণী যা কেবল তালিকার উপাদানগুলিকে অনুলিপি না করে সরাসরি অ্যাক্সেস করে।

কেবল নিশ্চিত হয়ে নিন iterator()যেহেতু এটি খালি হতে পারে বা nullবাস্তবায়নের উপর নির্ভর করে আপনি তার ফেরত পরীক্ষা করেছেন check


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

20
এটি সঠিক উত্তর হওয়া উচিত। উত্তরটি কেন সর্বদা "অন্য লাইব্রেরি ব্যবহার করুন!" কেন তা আমি বুঝতে পারি না! ।
কুজেকো

সংগ্রহের দ্বিতীয় উপাদানটি কেমন? প্রথম-> পরবর্তী () কেন কাজ করে না? আমার কি করা উচিৎ? ধন্যবাদ!
pb772

যথেষ্ট নিরাপদ নয়, এটি গ্যারান্টিযুক্ত নয় যে সংগ্রহটি সর্বদা প্রথম উপাদানটিকে নির্দেশ করবে।
পরবর্তী বিকাশকারী

84

জাভা 8:

Optional<String> firstElement = collection.stream().findFirst();

জাভা-র পুরানো সংস্করণগুলির জন্য পেয়ারা ইটারেবলস- এ একটি getFirst পদ্ধতি রয়েছে :

Iterables.getFirst(iterable, defaultValue)

6
জাভা 8 দ্রবণটি বিশেষত কার্যকর, কারণ এটি সংগ্রহটি দুর্দান্তভাবে খালি করার ক্ষেত্রে পরিচালনা করে।
স্পেসট্রকার

4
ভাল না. আপনি 4 টি লাইনের কোড লিখতে অলস হওয়ায় আপনি (0) পাওয়ার জন্য আপনি স্ট্রিমের ওভারহেড যুক্ত করুন (0)। যদি (! কালেকশন ইউটিস.আইএসপিটি (প্রোডাক্টলিস্ট)) {Optional.of (productList.get (0)) ফেরত দিন; } Optional.empty () ফিরিয়ে দিন;
আরএস

আমার কাছে getFirstপদ্ধতি নেই। রয়েছে getএবং getLastপদ্ধতিগুলি
ব্যবহারকারী 1209216

4
@ আরএস এবং যদি আপনি প্রোডাক্টলিস্ট.জেট (0) কল করতে না পারেন তবে এটি সংগ্রহ হিসাবে কী ঘটবে ..? (ওপি প্রশ্ন অনুসারে)
ডেনহাম কোট

40

Collectionএটিতে "প্রথম" আইটেমের মতো কোনও জিনিস নেই কারণ এটি কেবল একটি সংগ্রহ।

জাভা ডকের কালেকশন.ইয়েটার () পদ্ধতি থেকে:

যে উপাদানগুলিতে উপাদানগুলি ফিরে আসে সে সম্পর্কিত কোনও গ্যারান্টি নেই ...

সুতরাং আপনি পারবেন না।

আপনি যদি তালিকার মতো অন্য ইন্টারফেস ব্যবহার করেন তবে আপনি নিম্নলিখিতটি করতে পারেন:

String first = strs.get(0);

তবে সরাসরি কোনও সংগ্রহ থেকে এটি সম্ভব নয়।


11
আমি মনে করি নাget(int n)Collection
নিক হেইনার

2
আপনি ঠিক বলেছেন, আমি এই বিন্দু মিস করছি। আমি উত্তর আপডেট করেছি। আপনি পারবেন না! (যদি না সংগ্রহটি
আন্ডারলাইং

সংগ্রহ সংগ্রহের ইন্টারফেসে নেই
অ্যান্ডি গেরনা

21
অস্কার, আমি মনে করি আপনি কেসটিকে অতিরঞ্জিত করছেন। সংগ্রহের প্রথম উপাদানটি হ্যাশসেটের মতো কয়েকটি ক্ষেত্রে নির্বিচারে হতে পারে, তবে এটি ভালভাবে সংজ্ঞায়িত করা হয়েছে: এটি .iterator ()। পরবর্তী ()। এটি আমি স্থির প্রতিটি সংগ্রহ বাস্তবায়নেও স্থিতিশীল । (সম্পর্কিত: দয়া করে মনে রাখবেন করাকালীন আপনার সেট অর্ডার নিশ্চয়তা দেয় না, HashSet ব্যতীত JDK সেট এর প্রতি একক উপপ্রকার করে।)
কেভিন Bourrillion

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

4

আপনার সংগ্রহটি তালিকার মতো হতে চায় বলে মনে হচ্ছে, তাই আমি প্রস্তাব দিই:

List<String> myList = new ArrayList<String>();
...
String first = myList.get(0);

2

জাভা 8 আপনার ব্যবহারের জন্য কিছু অনেক অপারেটর, উদাহরণস্বরূপ আছে সীমা

     /**
 * Operator that limit the total number of items emitted through the pipeline
 * Shall print
 * [1]
 * @throws InterruptedException
 */
@Test
public void limitStream() throws InterruptedException {
    List<Integer> list = Arrays.asList(1, 2, 3, 1, 4, 2, 3)
                               .stream()
                               .limit(1)
                               .collect(toList());
    System.out.println(list);
}

2
@Vitalii Fedorenko এর উত্তর stackoverflow.com/a/18165855/1562662 উত্তম।
চকো ম্যাথিউ

2

পেয়ারা একটি সরবরাহ করে onlyElement Collectorতবে কেবল আপনি যদি সংগ্রহটি ঠিক একটি উপাদান হিসাবে প্রত্যাশা করেন তবে এটি ব্যবহার করুন।

Collection<String> stringCollection = ...;
String string = collection.stream().collect(MoreCollectors.onlyElement())

আপনি যদি সেখানে কতগুলি উপাদান সম্পর্কে নিশ্চিত না হন তবে ব্যবহার করুন findFirst

Optional<String> optionalString = collection.stream().findFirst();

1

আপনি একটি ingালাই করতে পারেন। উদাহরণস্বরূপ, যদি এই সংজ্ঞাটি সহ একটি পদ্ধতি বিদ্যমান থাকে এবং আপনি জানেন যে এই পদ্ধতিটি একটি তালিকা ফিরিয়ে দিচ্ছে:

Collection<String> getStrings();

এবং এটি আহ্বান করার পরে আপনার প্রথম উপাদানটির প্রয়োজন, আপনি এটি এটি করতে পারেন:

List<String> listString = (List) getStrings();
String firstElement = (listString.isEmpty() ? null : listString.get(0));

0

আপনি যদি জানেন যে সংগ্রহটি একটি সারি, তবে আপনি সংগ্রহটি একটি কাতারে কাস্ট করতে পারেন এবং সহজেই তা পেতে পারেন।

অর্ডারটি পেতে আপনি ব্যবহার করতে পারেন এমন বেশ কয়েকটি কাঠামো রয়েছে তবে আপনার এটিতে কাস্ট করতে হবে।


আমি সম্মত, আপনি পুনরাবৃত্তি করতে চান না, সংগ্রহ ব্যবহার করবেন না। পরিবর্তে আরও কিছু নির্দিষ্ট ইন্টারফেস ব্যবহার করুন।
আদিল আনসারী

1
যদিও আমি ভাবছি ... আসুন প্রকৃত অন্তর্নিহিত ডেটাটি একটি সাজানো সেট, তাই আদেশটি বোঝায়, তবে আপনার কেবল এটির সংগ্রহের ভিউ রয়েছে (নির্লজ্জ কারণে, আসুন বলি); যদি আপনি সংগ্রহটি কোনও তালিকায়, ক্যু ইত্যাদিতে ফেলে দেন এবং / পোল / ইত্যাদি করার চেষ্টা করেন, তখন কি বিপর্যয় দেখা দেয়? তেমনিভাবে, যদি অন্তর্নিহিত কাঠামো একটি তালিকা হয়, ইত্যাদি।
কার্ল

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

0

এটি সম্পূর্ণরূপে নির্ভর করে আপনি কোন প্রয়োগটি ব্যবহার করেছেন, অ্যারেলিস্ট লিঙ্কলিস্ট বা সেটটির অন্যান্য বাস্তবায়ন।

যদি এটি সেট করা থাকে তবে আপনি সরাসরি প্রথম উপাদানটি পেতে পারেন, এটি সংগ্রহের উপরের ট্রিক লুপ হতে পারে, মান 1 এর একটি ভেরিয়েবল তৈরি করতে পারে এবং পতাকাটির মানটি 1 হওয়ার পরে মানটি পেতে পারে সেই লুপটির পরে ব্রেক break

যদি এটি তালিকার বাস্তবায়ন হয় তবে সূচী সংখ্যাটি সংজ্ঞায়িত করে এটি সহজ।


0

কার্যকরী উপায়:

public static <T> Optional<T> findFirst(List<T> result) {
    return Optional.ofNullable(result)
            .map(List::stream)
            .flatMap(Stream::findFirst);
}

উপরের কোড স্নিপেট সংরক্ষণ করুন নালপয়েন্টারএক্সসেপশন এবং সূচিপত্র আউট অফফাউন্ডস এক্সসেপশন থেকে


1
আপনার পছন্দ List<T>শর্তে যে এটি একটি জন্য কাজ করা উচিত সন্তুষ্ট না Collection<String>, কিন্তু অবশ্যই যে ব্যবহার সংশোধন করা যেতে পারে এর Collection<T>অতিরিক্ত পরিবর্তনের সঙ্গে: .map(Collection::stream)
স্ক্র্যাটে

-2

আপনি এটি করতে পারেন:

String strz[] = strs.toArray(String[strs.size()]);
String theFirstOne = strz[0];

সংগ্রহের জন্য জাভাদোক নীচে অ্যারেগুলির উপাদানগুলির ক্র্যাটিং অর্ডার দেয়:

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


2
এটি একটি নতুন স্ট্রিং অ্যারে তৈরি করে, এটির তৈরির চেয়ে অনেক বেশি ব্যয়বহুল।
জিম ফেরানস

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

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