কোনও পুনরুক্তির গণনা / দৈর্ঘ্য / আকার পাওয়ার সর্বোত্তম উপায় কী?


100

পুনরাবৃত্তির গণনা পাওয়ার জন্য কোনও "গণনামূলক" দ্রুত উপায় আছে?

int i = 0;
for ( ; some_iterator.hasNext() ; ++i ) some_iterator.next();

... সিপিইউ চক্রের অপচয় হিসাবে মনে হচ্ছে।


4
একজন পুনরুক্তিকারীর অগত্যা একটি "গণনা" এর সাথে কোনও মিল নেই ...
অলিভার চার্লসওয়ার্থ

ইটারেটর তারা যা হয়; কোনও সংকলনের পরবর্তী বস্তুতে পুনরাবৃত্তি করতে (এটি সেট, অ্যারে ইত্যাদির মতো কিছু হতে পারে) তারা যখন পুনরাবৃত্তি করার চেষ্টা করছে তখন সেগুলি যত্নশীল না হলে তাদের আকারটি কেন বলা দরকার? to provide an implementation-independent method for access, in which the user does not need to know whether the underlying implementation is some form of array or of linked list, and allows the user go through the collection without explicit indexing. penguin.ewu.edu/~trolfe/LinkedSort/Iterator.html
eਕੇ

উত্তর:


67

যদি আপনি কেবলমাত্র পুনরুক্তি পেয়েছেন তবে এটিই আপনাকে করতে হবে - এটি জানেন না যে এটি কতগুলি আইটেমটি পুনরাবৃত্তি করতে বাকি ছিল, তাই আপনি ফলাফলটির জন্য এটি জিজ্ঞাসা করতে পারবেন না। এমন কিছু ইউটিলিটি পদ্ধতি রয়েছে যা দেখে মনে হয় (যেমন Iterators.size()পেয়ারা হিসাবে ) তবে তারা কেবলমাত্র একই অপারেশনটি সম্পাদন করছে।

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

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


এর পার্শ্ব-প্রতিক্রিয়া সম্পর্কে সতর্ক থাকুন Iterators.size(...)(নীচে এবং জাভা-ডকের অন্যান্য মন্তব্যে উল্লিখিত): "পুনরুক্তিতে থাকা উপাদানগুলির সংখ্যা ফেরত দেয় The তার মানে, আপনি এর পরে আর আইট্রেটার ব্যবহার করতে পারবেন না। Lists.newArrayList(some_iterator);সাহায্য করতে পারে.
মাইকেলকলার

91

পেয়ারা গ্রন্থাগার ব্যবহার :

int size = Iterators.size(iterator);

অভ্যন্তরীণভাবে এটি সমস্ত উপাদানগুলির উপরে পুনরাবৃত্তি করে তাই এটি কেবল সুবিধার জন্য।


8
এটি খুব মার্জিত। কেবল মনে রাখবেন যে আপনি আপনার পুনরাবৃত্তকারী গ্রাস করছেন (যেমন, পুনরুক্তিটি পরে খালি হবে)
লোসকি

4
এটি "গণনামূলকভাবে দ্রুত" নয়, এটি একটি সুবিধা পদ্ধতি যা পুনরুক্তি গ্রহণের অনাকাঙ্ক্ষিত পার্শ্ব প্রতিক্রিয়া রাখে।
জাক

আপনি দয়া করে ব্যাখ্যা করতে পারেন যে এটি কীভাবে কাজ করে? @ আন্ড্রেজ তালিকা <টিপল 2 <স্ট্রিং, পূর্ণসংখ্যক >> wordCountsWithGroupByKey = wordsPairRdd.groupByKey ()। ম্যাপভ্যালুইস (অন্তঃসত্ত্বা -> Iterables.size (intIteable)) সংগ্রহ (); System.out.println ("wordCountsWithGroupByKey:" + wordCountsWithGroupByKey); "Iterables.size (intIterable)?
আদিত্য ভার্মা

15

আপনার কোডটি আপনাকে একটি ব্যতিক্রম দেয় যখন আপনি পুনরাবৃত্তির শেষে পৌঁছে যান। আপনি করতে পারেন:

int i = 0;
while(iterator.hasNext()) {
    i++;
    iterator.next();
}

অন্তর্নিহিত সংগ্রহটিতে যদি আপনার অ্যাক্সেস থাকে তবে আপনি কল করতে সক্ষম হবেন coll.size()...

সম্পাদনা করুন ঠিক আছে আপনি সংশোধন করেছেন ...


এটা কতটা দক্ষ? যদি পুনরুক্তি এক মিলিয়ন মূল্য হিসাবে হয়?
মাইক্রো

4
@ মাইক্রো প্রযুক্তিগতভাবে একটি পুনরুক্তি অসীম হতে পারে - এক্ষেত্রে লুপটি চিরতরে চলে যাবে।
Assylias

12

আপনাকে সর্বদা পুনরাবৃত্তি করতে হবে। তবুও আপনি জাভা 8, 9 টি স্পষ্টভাবে লুপিং ছাড়াই গণনা করতে ব্যবহার করতে পারেন:

Iterable<Integer> newIterable = () -> iter;
long count = StreamSupport.stream(newIterable.spliterator(), false).count();

এখানে একটি পরীক্ষা:

public static void main(String[] args) throws IOException {
    Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4, 5).iterator();
    Iterable<Integer> newIterable = () -> iter;
    long count = StreamSupport.stream(newIterable.spliterator(), false).count();
    System.out.println(count);
}

এই মুদ্রণ:

5

যথেষ্ট আকর্ষণীয় আপনি parallelএই কলটিতে পতাকা পরিবর্তন করে এখানে গণনা ক্রিয়াকে সমান্তরাল করতে পারেন :

long count = StreamSupport.stream(newIterable.spliterator(), *true*).count();

8

পেয়ারা লাইব্রেরি ব্যবহার করে , অন্য একটি বিকল্প হ'ল এটিকে রূপান্তর Iterableকরা List

List list = Lists.newArrayList(some_iterator);
int count = list.size();

যদি আপনার পুনরুক্তি আকারের পরে উপাদানগুলির অ্যাক্সেস করার প্রয়োজন হয় তবে এটি ব্যবহার করুন। Iterators.size()আপনি ব্যবহার করে আর পুনরাবৃত্তি উপাদান অ্যাক্সেস করতে পারবেন না।


4
@ লাভটোকোড মূল প্রশ্নের উদাহরণের চেয়ে কম দক্ষ
শীতকালীন

4
অবশ্যই, সমস্ত উপাদানগুলির সাথে একটি নতুন অবজেক্ট তৈরি করা কেবল পুনরাবৃত্তি এবং ত্যাগের চেয়ে ধীর। আইএমএইচও, এই সমাধানটি একটি ওয়ান-লাইনার যা কোডের পঠনযোগ্যতার উন্নতি করে। আমি এটি কয়েকটি উপাদান (1000 অবধি) সহ সংগ্রহের জন্য বা গতি যখন কোনও সমস্যা নয় তখন ব্যবহার করি।
tashuhka

7

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

মনে রাখবেন যে আইট্রেটর স্বতন্ত্র মানগুলি অনুসরণ করার জন্য কেবল একটি ইন্টারফেস, আপনার কাছে খুব ভাল কোড রয়েছে

    new Iterator<Long>() {
        final Random r = new Random();
        @Override
        public boolean hasNext() {
            return true;
        }

        @Override
        public Long next() {
            return r.nextLong();
        }

        @Override
        public void remove() {
            throw new IllegalArgumentException("Not implemented");
        }
    };

বা

    new Iterator<BigInteger>() {
        BigInteger next = BigInteger.ZERO;

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

        @Override
        public BigInteger next() {
            BigInteger current = next;
            next = next.add(BigInteger.ONE);
            return current;
        }

        @Override
        public void remove() {
            throw new IllegalArgumentException("Not implemented");
        }
    }; 

4

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

সমাধানটি হ'ল আপনার অ্যাপ্লিকেশনটি পরিবর্তন করা যাতে এটির গণনার প্রয়োজন না হয়, বা অন্য কোনও উপায়ে গণনা অর্জন করা। (উদাহরণস্বরূপ, এর Collectionচেয়ে পাস করুন Iterator...)


0

জন্য জাভা 8 আপনি ব্যবহার করতে পারে,

public static int getIteratorSize(Iterator iterator){
        AtomicInteger count = new AtomicInteger(0);
        iterator.forEachRemaining(element -> {
            count.incrementAndGet();
        });
        return count.get();
    }

-6

পুনরুক্তিকারী অবজেক্টটিতে আপনার সংকলনটিতে যে পরিমাণ উপাদান রয়েছে তা একই পরিমাণে রয়েছে।

List<E> a =...;
Iterator<E> i = a.iterator();
int size = a.size();//Because iterators size is equal to list a's size.

তবে পুনরাবৃত্তির আকার পেতে এবং সূচক 0 দিয়ে সেই আকারে পুনরাবৃত্তি করার পরিবর্তে পুনরুক্তরের পরবর্তী () পদ্ধতির মাধ্যমে পুনরাবৃত্তি করা ভাল ।


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