উত্তর:
পেয়ারার মতো লাইব্রেরি ব্যবহার করা ভাল :
import com.google.common.collect.Lists;
Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
আর এক পেয়ারা উদাহরণ:
ImmutableList.copyOf(myIterator);
import org.apache.commons.collections.IteratorUtils;
Iterator<Element> myIterator = ...//some iterator
List<Element> myList = IteratorUtils.toList(myIterator);
জাভা 8-এ, আপনি ইন্টারফেসে forEachRemaining
যুক্ত হওয়া নতুন পদ্ধতিটি ব্যবহার করতে পারেন Iterator
:
List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
::
? এর নাম কি? list.add () এর সরাসরি উল্লেখ বলে মনে হচ্ছে; এবং কিছু java8 নতুন জিনিস মনে হয়; এবং ধন্যবাদ! :)
::
জাভা 8- এ সিনট্যাক্সটি নতুন, এবং এটি একটি "পদ্ধতির রেফারেন্স" বোঝায় যা ল্যাম্বদার একটি সংক্ষিপ্ত রূপ। আরও তথ্যের জন্য এখানে দেখুন: docs.oracle.com/javase/tutorial/java/javaOO/…
iterator
থেকে আসছে? এটি একটি অমীমাংসিত প্রতীক
iterator
।
আপনি এই জাতীয় একটি নতুন তালিকায় একটি পুনরাবৃত্তি কপি করতে পারেন:
Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
copy.add(iter.next());
এটি ধরে নিচ্ছি যে তালিকায় স্ট্রিং রয়েছে। কোনও পুনরুক্তিকারীর কাছ থেকে তালিকাটি পুনরায় তৈরি করার সত্যি কোনও দ্রুত উপায় নেই, আপনি এটি হাত দ্বারা অনুসরণ করে এবং প্রতিটি উপাদানকে উপযুক্ত ধরণের নতুন তালিকায় অনুলিপি করতে আটকে রয়েছেন।
সম্পাদনা:
টাইপ-নিরাপদ উপায়ে একটি নতুন তালিকায় কোনও পুনরাবৃত্তিকারীকে অনুলিপি করার জন্য একটি জেনেরিক পদ্ধতি রয়েছে:
public static <T> List<T> copyIterator(Iterator<T> iter) {
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
এটি এর মতো ব্যবহার করুন:
List<String> list = Arrays.asList("1", "2", "3");
Iterator<String> iter = list.iterator();
List<String> copy = copyIterator(iter);
System.out.println(copy);
> [1, 2, 3]
নোট করুন Iterable
এবং এর মধ্যে পার্থক্য রয়েছে Iterator
।
আপনার যদি একটি থাকে Iterable
তবে জাভা 8 এর সাহায্যে আপনি এই সমাধানটি ব্যবহার করতে পারেন:
Iterable<Element> iterable = createIterable();
List<Element> array = StreamSupport
.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
আমি জানি যেমন উদাহরণ Collectors.toList()
তৈরি করে ArrayList
।
আসলে আমার মতে এটি এক লাইনেও ভাল লাগছে।
উদাহরণস্বরূপ যদি আপনার List<Element>
কোনও পদ্ধতি থেকে ফিরে আসতে হয়:
return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Iterable
iterator
। এগুলি সম্পূর্ণ আলাদা।
Iterator
একটি ফিরে একক ব্যবহার Iterable
ব্যবহার করে () -> iterator
। এটি এর মতো পরিস্থিতিতে কার্যকর হতে পারে তবে আমাকে গুরুত্বপূর্ণ বিষয়টিকে আবার জোর দেওয়া উচিত: আপনি যদি এই পদ্ধতিটি কেবল তখনই গ্রহণ করতে পারেন তবে Iterable
তা গ্রহণযোগ্য। iterable.iterator()
একাধিকবার কল করা অপ্রত্যাশিত ফলাফল পাবে। উপরের উত্তরটি তখন হয়ে যায়Iterator<Element> iterator = createIterator();
List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
আপনি IteratorUtils
অ্যাপাচি কমন্স-সংগ্রহ থেকেও ব্যবহার করতে পারেন , যদিও এটি জেনেরিকগুলি সমর্থন করে না:
List list = IteratorUtils.toList(iterator);
প্লেন জাভা 8 ব্যবহার করে সুন্দর সংক্ষিপ্ত সমাধান java.util.stream
:
public static <T> ArrayList<T> toArrayList(final Iterator<T> iterator) {
return StreamSupport
.stream(
Spliterators
.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
.collect(
Collectors.toCollection(ArrayList::new)
);
}
iterator.forEachRemaining( list::add )
, জাভা 8-তেও নতুন, এটি আরও অনেক সংক্ষিপ্ত। তালিকার ভেরিয়েবলটিকে এতে Collector
চাপানো এ ক্ষেত্রে পঠনযোগ্যতার উন্নতি করে না, যেহেতু এটি a Stream
এবং a দ্বারা সমর্থন করা উচিত Spliterator
।
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
ক্যাকটুসStickyList
থেকে চেষ্টা করুন :
List<String> list = new StickyList<>(iterable);
দাবি অস্বীকার: আমি অন্যতম বিকাশকারী।
Iterable
! =Iterator
আমি কেবল একটি আপাতদৃষ্টিতে সুস্পষ্ট সমাধানটি নির্দেশ করতে চাই যা কার্যকর হবে না :
তালিকা তালিকা = স্ট্রিম.জেনারেট (পুনরুক্তিকারী :: পরের) .collect (Collectors.toList ());
এটি কারণ Stream#generate(Supplier<T>)
কেবলমাত্র অসীম স্ট্রিম তৈরি করতে পারে, এটি তার যুক্তি নিক্ষেপ করার আশা করে না NoSuchElementException
( Iterator#next()
এটিই শেষ পর্যন্ত কী করবে)।
Xehpuk এর উত্তর পরিবর্তে ব্যবহার করা উচিত যদি Iterator → স্ট্রিম → তালিকার উপায়টি আপনার পছন্দ হয়।
গুগল পেয়ারা ব্যবহার করুন !
Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);
++,
এখানে এই ক্ষেত্রে আপনি যদি দ্রুততম উপায় চান তবে for loop
আরও ভাল।
একটি নমুনা আকার উপর পুনরুক্তিকারীর 10,000 runs
লাগে 40 ms
যেখানে হিসাবে লুপ লাগে2 ms
ArrayList<String> alist = new ArrayList<String>();
long start, end;
for (int i = 0; i < 1000000; i++) {
alist.add(String.valueOf(i));
}
ListIterator<String> it = alist.listIterator();
start = System.currentTimeMillis();
while (it.hasNext()) {
String s = it.next();
}
end = System.currentTimeMillis();
System.out.println("Iterator start: " + start + ", end: " + end + ", delta: "
+ (end - start));
start = System.currentTimeMillis();
int ixx = 0;
for (int i = 0; i < 100000; i++) {
String s = alist.get(i);
}
System.out.println(ixx);
end = System.currentTimeMillis();
System.out.println("for loop start: " + start + ", end: " + end + ", delta: "
+ (end - start));
এটি ধরে নিচ্ছি যে তালিকায় স্ট্রিং রয়েছে।
for
লুপ ব্যবহার করা এবং এর সাথে তালিকার উপাদানগুলিতে অ্যাক্সেস get(i)
করা একটি আয়রেটর ব্যবহারের চেয়ে দ্রুততর ... তবে ওপি যা বলছিল তা নয়, তিনি বিশেষভাবে উল্লেখ করেছিলেন যে একটি পুনরুক্তিটিকে ইনপুট হিসাবে দেওয়া হয়।
get(int)
লুপ আপনি শুধুমাত্র 1 মি এন্ট্রির 100 কিলোবাইট এ খুঁজছেন। আপনি যদি সেই লুপটি পরিবর্তন করেন তবে আপনি it.size()
দেখতে পাবেন যে এই 2 টি পদ্ধতি একই গতির কাছে রয়েছে। সাধারণভাবে এই ধরণের জাভা স্পিড পরীক্ষাগুলি বাস্তব জীবনের পারফরম্যান্সের সীমাবদ্ধ তথ্য সরবরাহ করে এবং সন্দিহানভাবে দেখা উচিত।