জাভাতে একটি Iteable আকার পান


90

Iterableজাভাতে আমার উপাদানগুলির সংখ্যা বের করতে হবে । আমি জানি আমি এটি করতে পারি:

Iterable values = ...
it = values.iterator();
while (it.hasNext()) {
  it.next();
  sum++;
}

আমি এটির মতোও কিছু করতে পারি, কারণ আমার আর আইট্রেলেবলের প্রয়োজন নেই:

it = values.iterator();
while (it.hasNext()) {
  it.remove();
  sum++;
}

একটি ছোট স্কেলের বেঞ্চমার্ক খুব বেশি পারফরম্যান্সের পার্থক্য দেখায় না, এই সমস্যার জন্য কোনও মন্তব্য বা অন্যান্য ধারণা?


কেন? হয় উভয়ই (এন) হিসাবে সত্যই খারাপ ধারণা। আপনার সংগ্রহটি দুবার পুনরাবৃত্তি করা এড়াতে চেষ্টা করা উচিত।
ব্যবহারকারী 207421

4
আপনার দ্বিতীয়টি এমনকি কাজ করা উচিত নয়। আপনি কল করতে পারবেন না remove()কলিং ছাড়া next()পূর্বেই।
লুই ওয়াসারম্যান

উত্তর:


125

টিএল; ডিআর: Iterables.size(Iterable)দুর্দান্ত পেয়ারা গ্রন্থাগারের ইউটিলিটি পদ্ধতিটি ব্যবহার করুন ।

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

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

সাধারণভাবে, যদি এমন সুযোগ থাকে যা valuesপ্রকৃতপক্ষে কেবলমাত্র একটিই Collectionনয় তবে এটি Iterableপরীক্ষা করে দেখুন এবং কল করুন size():

if (values instanceof Collection<?>) {
  return ((Collection<?>)values).size();
}
// use Iterator here...

থেকে কল size()ইচ্ছা সাধারণত অনেক দ্রুত উপাদানের সংখ্যা বেড়ে চলেছে চেয়ে, এবং এই কৌতুক ঠিক কি Iterables.size(Iterable)এর পেয়ারা তোমার জন্য না।


তিনি বলেছিলেন যে তিনি উপাদানগুলির প্রতি আগ্রহী নন এবং সেগুলি সরিয়ে দেওয়া হচ্ছে কিনা সেদিকে খেয়াল নেই।
আইয়ুব

ছোট স্পষ্টকরণ: এটি থেকেvalues
মিকেল

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

আমি গুগল পেয়ারা উত্তর আরও বিশিষ্ট করার পরামর্শ দিচ্ছি। লোকেদের এই কোডটি তুচ্ছ বলে মনে করে আবার লেখার কোনও কারণ নেই।
স্টিফেন হ্যারিসন

8
আপনি যদি জাভা 8 ব্যবহার করেন তবে একটি স্ট্রিম তৈরি করুন এবং এটিতে উপাদান গণনা করুন: স্ট্রিম.ওফ (মাই আইটেবল) .কাউন্ট ()
ফ্রাঙ্কবিআর

41

আপনি যদি জাভা 8 নিয়ে কাজ করছেন তবে আপনি এটি ব্যবহার করতে পারেন:

Iterable values = ...
long size = values.spliterator().getExactSizeIfKnown();

এটি কেবল তখনই কাজ করবে যদি পুনরাবৃত্তিযোগ্য উত্সটির একটি নির্ধারিত আকার থাকে। সংগ্রহের জন্য সর্বাধিক স্প্লিটেটররা হ'ল তবে এটি যদি কোনও HashSetবা ResultSetউদাহরণ থেকে আসে তবে আপনার সমস্যা হতে পারে ।

আপনি জাভাডোক এখানে পরীক্ষা করতে পারেন

যদি জাভা 8 কোনও বিকল্প না হয় বা আপনি যদি না জানেন তবে পুনরাবৃত্তিযোগ্য কোথা থেকে আসে তবে আপনি পেয়ারা হিসাবে একই পদ্ধতির ব্যবহার করতে পারেন:

  if (iterable instanceof Collection) {
        return ((Collection<?>) iterable).size();
    } else {
        int count = 0;
        Iterator iterator = iterable.iterator();
        while(iterator.hasNext()) {
            iterator.next();
            count++;
        }
        return count;
    }

4
কেউ, এই লোকটিকে একটি মেডেল দিন।
বজ্রাচার্য

বাছাইয়ের জন্য এটি আমার পক্ষে কাজ করে না । নিউ মৌমাছির উত্তর আমার পক্ষে কাজ করে।
সাবির খান

18

এটি সম্ভবত কিছুটা দেরি হয়েছে, তবে কাউকে সাহায্য করতে পারে। আমি Iterableআমার কোডবেসে একই ধরণের সমস্যাটি দেখতে পাচ্ছি এবং সমাধানটি for eachস্পষ্টভাবে কল না করে ব্যবহার করা ছিল values.iterator();

int size = 0;
for(T value : values) {
   size++;
}

4
এটি আমার কাছে একটি স্বজ্ঞাত পদ্ধতি, যা আমি প্রশংসা করতে পারি। কয়েক মিনিট আগে এটি ব্যবহার করেছেন। ধন্যবাদ
ম্যাট ক্রিমেন্স

4
হ্যাঁ এটি স্বজ্ঞাত, তবে দুঃখের সাথে আপনাকে মানটির জন্য অব্যবহৃত-সতর্কতা দমন করতে হবে ...
নীলস-ও-মাদুর

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

6

কড়া কথায় বলতে গেলে, আইটেচারের আকার থাকে না। চক্রের মতো ডেটা স্ট্রাকচার ভাবুন।

এবং অনুসরণযোগ্য উদাহরণগুলি সম্পর্কে চিন্তা করুন, কোনও আকার নয়:

    new Iterable(){

        @Override public Iterator iterator() {
            return new Iterator(){

                @Override
                public boolean hasNext() {
                    return isExternalSystemAvailble();
                }

                @Override
                public Object next() {
                    return fetchDataFromExternalSystem();
                }};
        }};

6

আপনি আপনার পুনরাবৃত্তিকে তালিকায় ফেলে দিতে পারেন তারপরে .size () ব্যবহার করুন।

Lists.newArrayList(iterable).size();

স্পষ্টতার স্বার্থে, উপরের পদ্ধতিটির জন্য নিম্নলিখিত আমদানি প্রয়োজন:

import com.google.common.collect.Lists;

4
তালিকাগুলি একটি পেয়ারা ক্লাস
পল জ্যাকসন

2

আমি কার্যকর করার it.next()জন্য যে next()গ্যারান্টিযুক্ত সেই সাধারণ কারণে যাব , যদিও remove()এটি একটি alচ্ছিক অপারেশন।

E next()

পুনরাবৃত্তির পরবর্তী উপাদানটি প্রদান করে।

void remove()

অন্তর্নিহিত সংগ্রহ থেকে সরানো শেষ উপাদানটি পুনরাবৃত্তকারী ( alচ্ছিক ক্রিয়াকলাপ) দ্বারা ফিরে এসেছে ।


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

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


0

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


-2

উপাদানগুলির সংখ্যা পেতে আপনি কেবল নিজের size()পদ্ধতিটি ব্যবহার করেন না কেন Collection?

Iterator শুধু পুনরাবৃত্তি বোঝানো হয়, অন্য কিছুই।


4
কে বলে যে সে কোন সংগ্রহ ব্যবহার করছে? :-)
আইয়ুব

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

4
আকার অনুসন্ধানের জন্য তাঁর কেন সংগ্রহ নাও হতে পারে তার একটি উদাহরণ: তিনি একটি তৃতীয় পক্ষের এপিআই পদ্ধতিতে কল করতে পারেন যা কেবলমাত্র একটি আইটেমারেবল ফিরিয়ে দেয়।
স্টিভটি

4
এই উত্তর বিভ্রান্ত Iteratorএবং Iterable। সঠিক ভাবে ভোট দেওয়া উত্তর দেখুন See
স্টিফেন হ্যারিসন

-4

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

((ArrayList) iterable).size();

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