আমি জাভাতে ক্রমিক সংখ্যার তালিকা বা অ্যারে কীভাবে তৈরি করতে পারি?


130

একটি List<Integer>, বা সম্ভবত একটি Integer[]বা int[]কিছু থেকে ক্রমান্বিত মানগুলি startএকটি মান থেকে উত্পন্ন করার জন্য একটি ছোট এবং মিষ্টি উপায় আছে end?

এটি হ'ল, এর চেয়ে ছোট কিছু কিন্তু নিম্নলিখিত 1 টির সমতুল্য :

void List<Integer> makeSequence(int begin, int end) {
  List<Integer> ret = new ArrayList<>(end - begin + 1);
  for (int i=begin; i<=end; i++) {
    ret.add(i);
  }
  return ret;  
}

পেয়ারার ব্যবহার ঠিক আছে।

হালনাগাদ:

কর্মক্ষমতা বিশ্লেষণ

যেহেতু এই প্রশ্নটি বেশ কয়েকটি ভাল উত্তর পেয়েছে, উভয়ই নেটিভ জাভা 8 এবং তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করে, আমি ভেবেছিলাম যে আমি সমস্ত সমাধানগুলির কার্যকারিতা পরীক্ষা করব।

প্রথম পরীক্ষাটি [1..10]নিম্নলিখিত পদ্ধতিগুলি ব্যবহার করে 10 টি উপাদানের একটি তালিকা তৈরি করার পরীক্ষা করে:

  • ClassAArayLList : আমার প্রশ্নের উপরে বর্ণিত কোড (এবং মূলত আদর্শের উত্তর হিসাবে একই)।
  • গ্রহনক্ষেত্র সংগ্রহ: নিচের দিকে ডোনাল্ডের উত্তরে গ্রীকস সংগ্রহ 8.0 ব্যবহার করে দেওয়া কোড ।
  • পেয়ারাঞ্জেজ : নীচে দাভবের উত্তরে দেওয়া কোড । প্রযুক্তিগতভাবে, এটি একটি List<Integer>নয় বরং একটি তৈরি করে ContiguousSet<Integer>- তবে যেহেতু এটি ক্রমটি কার্যকর Iterable<Integer>করে, এটি বেশিরভাগ ক্ষেত্রে আমার উদ্দেশ্যে কাজ করে।
  • ইন্টস্ট্রিমরেঞ্জ : নীচে ভ্লাদিমিরের উত্তরে প্রদত্ত কোড , যা ব্যবহার করে IntStream.rangeClosed()- যা জাভা 8-এ চালু হয়েছিল।
  • স্ট্রিমিট্রেট : নীচে ক্যাটালিনের উত্তরে প্রদত্ত কোড যা IntStreamজাভা 8-তে প্রবর্তিত কার্যকারিতাও ব্যবহার করে।

উপরের সমস্তটির জন্য এখানে প্রতি সেকেন্ডে কিলো-অপারেশনের ফলাফল রয়েছে (উচ্চতর সংখ্যা আরও ভাল), মাপের 10 টির তালিকা সহ:

তালিকা তৈরির মাধ্যমে

... এবং আবার 10,000 টি আকারের তালিকার জন্য:

এখানে চিত্র বর্ণনা লিখুন

শেষের চার্টটি সঠিক - এক্লিপস এবং পেয়ারা ব্যতীত অন্যান্য সমাধানগুলি এমনকি একটি পিক্সেল বার পেতে খুব ধীর হয়! দ্রুত সমাধানগুলি বাকীগুলির চেয়ে 10,000 থেকে 20,000 গুণ বেশি দ্রুত।

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

আসুন আমরা আরও কিছু বাস্তবসম্মত কিছু করি এবং সমস্ত সংখ্যার সংগে সংক্ষেপে পুনরাবৃত্তি করি। সুতরাং IntStream.rangeClosedবৈকল্পিকের ক্ষেত্রে , মাপদণ্ডটি এমন দেখাচ্ছে:

@Benchmark
public int intStreamRange() {
    List<Integer> ret = IntStream.rangeClosed(begin, end).boxed().collect(Collectors.toList());  

    int total = 0;
    for (int i : ret) {
        total += i;
    }
    return total;  
}

এখানে, চিত্রগুলি অনেক পরিবর্তন করে, যদিও অ অ-বস্তুগত সমাধানগুলি এখনও সবচেয়ে দ্রুত। এখানে দৈর্ঘ্য = 10:

তালিকা <ইন্টেগার> আইট্রেশন (দৈর্ঘ্য = 10)

... এবং দৈর্ঘ্য = 10,000:

তালিকা <ইন্টেগার> আইট্রেশন (দৈর্ঘ্য = 10,000)

অনেক উপাদানগুলির উপর দীর্ঘ পুনরাবৃত্তি অনেকগুলি জিনিসকে সন্নিবিষ্ট করে, তবে 10,000 উপাদান পরীক্ষায়ও গ্রহ এবং পেয়ারা দ্বিগুণের বেশি দ্রুত থেকে যায়।

সুতরাং আপনি যদি সত্যই চান তবে List<Integer>গ্রহগ্রহের সংগ্রহগুলি সেরা পছন্দ হিসাবে মনে হয় - তবে অবশ্যই যদি আপনি আরও স্থানীয় উপায়ে স্ট্রিম ব্যবহার করেন (যেমন, .boxed()আদিম ডোমেনে ভুলে যাওয়া এবং হ্রাস করা) আপনি সম্ভবত এই সমস্তগুলির চেয়ে দ্রুত শেষ করবেন রূপগুলো।


1 সম্ভবত ত্রুটি পরিচালনার ব্যতীত উদাহরণস্বরূপ, যদি end< begin, বা আকারটি কিছু বাস্তবায়ন বা জেভিএম সীমা অতিক্রম করে (যেমন, এর চেয়ে বড় অ্যারেগুলি) 2^31-1


Apache কমন্স জন্য stackoverflow.com/a/5744861/560302
MoveFast

উত্তর:


185

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

List<Integer> range = IntStream.rangeClosed(start, end)
    .boxed().collect(Collectors.toList());

2
আমি এই উত্তরের জন্য পারফরম্যান্স ফলাফলগুলি অন্তর্ভুক্ত করেছি স্ট্রিম্যাঞ্জ লেবেল ।
BeeOnRope

এপিআই 24+
gcantoni

28

ভাল, এই এক লাইনার যোগ্যতা অর্জন করতে পারে ( পেয়ারা রেঞ্জ ব্যবহার করে )

ContiguousSet<Integer> integerList = ContiguousSet.create(Range.closedOpen(0, 10), DiscreteDomain.integers());
System.out.println(integerList);

এটি একটি তৈরি করে না List<Integer>, তবে ContiguousSetঅনেকগুলি একই কার্যকারিতা সরবরাহ করে, বিশেষত প্রয়োগকারী Iterable<Integer>যা foreachএকইভাবে বাস্তবায়নের অনুমতি দেয় List<Integer>

পুরানো সংস্করণগুলিতে (পেয়ারা 14 এর আগে কোথাও) আপনি এটি ব্যবহার করতে পারেন:

ImmutableList<Integer> integerList = Ranges.closedOpen(0, 10).asSet(DiscreteDomains.integers()).asList();
System.out.println(integerList);

উভয় উত্পাদন:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

7
asList()আপনার সত্যিকারের দরকার না হলে আমি সেখানে ব্যবহার করব না List... ContiguousSetউত্পাদিত asSetহালকা ওজনের হয় (এটির জন্য কেবল পরিসর এবং ডোমেনের প্রয়োজন হয়), তবে asList()একটি তালিকা তৈরি করবে যা আসলে মেমরির (বর্তমানে) সমস্ত উপাদান সঞ্চয় করে।
কলিনড

1
একমত। ওপি যদিও তালিকা বা অ্যারের জন্য জিজ্ঞাসা করছিল, অন্যথায় আমি এটি ছেড়ে দিতাম
daveb

1
আমি 18.0 এর জন্য বিশ্বাস করি, Rangeবিদ্যমান কিন্তু তা নেই Rangesএবং তারা asSetপদ্ধতিটি শেষ করে দিয়েছে। আমার পুরানো সংস্করণে, asSetঅবহেলা করা হয়েছে এবং দেখা যাচ্ছে যে তারা এটি সরিয়ে নিয়েছে। বাহ্যত স্পষ্টতই কেবল সংলগ্ন সংগ্রহের জন্য ব্যবহৃত হবে এবং তারা এটি প্রয়োগ করেছে যদিও আমি এই সমাধানটি পছন্দ করি না।
ডেমোঙ্গোলেম

এপিআই-তে এখন এর অনুরূপ কোডের প্রয়োজন: কনটিজিউটসেট কোড্রিট (রেঞ্জক্লোকড (1, গণনা), ডিসক্রিটডোমাইন ইন্টিজার্স ()
বেন

আমি এই উত্তরটির জন্য পারফরম্যান্সের ফলাফলগুলিকে পেয়ারা রেঞ্জের লেবেল যুক্ত করেছি
BeeOnRope

11

নিম্নলিখিত ওয়ান-লাইনার জাভা 8 সংস্করণ [1, 2, 3 ... 10] উত্পন্ন করবে। প্রথম ARG iterateক্রমানুসারে প্রথম NR, এবং প্রথম ARG limitশেষ নম্বর।

List<Integer> numbers = Stream.iterate(1, n -> n + 1)
                              .limit(10)
                              .collect(Collectors.toList());

আমি উপরের উত্তরটির জন্য পারফরম্যান্সের ফলাফলগুলি লেবেল স্ট্রিমিট্রেট দিয়ে জুড়েছি
BeeOnRope

1
স্পষ্টকরণের পয়েন্ট হিসাবে, সীমাটি আরগটি শেষ সংখ্যা নয়, এটি তালিকার পূর্ণসংখ্যার সংখ্যা।
নীলিরসন

7

আপনি ক্লিপস সংগ্রহInterval থেকে ক্লাসটি ব্যবহার করতে পারেন ।

List<Integer> range = Interval.oneTo(10);
range.forEach(System.out::print);  // prints 12345678910

Intervalশ্রেণী অলস, তাই মূল্যবোধের সব সঞ্চয় করবে না।

LazyIterable<Integer> range = Interval.oneTo(10);
System.out.println(range.makeString(",")); // prints 1,2,3,4,5,6,7,8,9,10

আপনার পদ্ধতিটি নিম্নলিখিত হিসাবে প্রয়োগ করা যেতে সক্ষম হবে:

public List<Integer> makeSequence(int begin, int end) {
    return Interval.fromTo(begin, end);
}

আপনি পূর্ণসংখ্যার যেমন বক্সিং আছে ints এড়াতে চাই, কিন্তু এখনও ফলে একটি তালিকা গঠন মত, তাহলে আপনি ব্যবহার করতে পারেন তাহলে IntListসঙ্গে IntIntervalঅন্ধকার সংগ্রহগুলি থেকে।

public IntList makeSequence(int begin, int end) {
    return IntInterval.fromTo(begin, end);
}

IntListহয়েছে পদ্ধতি sum(), min(), minIfEmpty(), max(), maxIfEmpty(), average()এবং median()ইন্টারফেসে পাওয়া যায়।

স্পষ্টতার জন্য আপডেট: 11/27/2017

আন Intervalএকটি List<Integer>, তবে এটি অলস এবং অপরিবর্তনীয়। এটি পরীক্ষার ডেটা উত্পন্ন করার জন্য অত্যন্ত কার্যকর, বিশেষত যদি আপনি সংগ্রহের সাথে অনেক কিছু করেন। আপনি যদি চান তবে খুব সহজেই একটিতে একটি অন্তর্বল অনুলিপি করতে পারেন List, Setবা Bagনিম্নলিখিত হিসাবে:

Interval integers = Interval.oneTo(10);
Set<Integer> set = integers.toSet();
List<Integer> list = integers.toList();
Bag<Integer> bag = integers.toBag();

আন IntIntervalএকটি ImmutableIntListযা প্রসারিত হয় IntList। এর কনভার্টার পদ্ধতিও রয়েছে।

IntInterval ints = IntInterval.oneTo(10);
IntSet set = ints.toSet();
IntList list = ints.toList();
IntBag bag = ints.toBag();

একটি Intervalএবং একটির IntIntervalএকই equalsচুক্তি নেই।

এক্সিলিপ সংগ্রহের জন্য আপডেট 9.0

আপনি এখন আদিম স্ট্রিম থেকে আদিম সংগ্রহ তৈরি করতে পারেন। আপনার পছন্দ উপর নির্ভর করে আছে withAllএবং ofAllপদ্ধতি আছে । আপনি যদি কৌতূহলী হন তবে আমি এখানে উভয় কেন আছে তা ব্যাখ্যা করি । এই পদ্ধতিগুলি পরিবর্তনীয় এবং অপরিবর্তনীয় ইন্টার / লং / ডাবল তালিকা, সেট, ব্যাগ এবং স্ট্যাকের জন্য বিদ্যমান।

Assert.assertEquals(
        IntInterval.oneTo(10),
        IntLists.mutable.withAll(IntStream.rangeClosed(1, 10)));

Assert.assertEquals(
        IntInterval.oneTo(10),
        IntLists.immutable.withAll(IntStream.rangeClosed(1, 10)));

দ্রষ্টব্য: আমি গ্রহগ্রাহ সংগ্রহের প্রতিশ্রুতিবদ্ধ


আমি উপরের এই উত্তরটির জন্য কর্মক্ষেত্রের ফলাফলগুলি গ্রহগ্রাহ সংগ্রহগুলি লেবেল সহ উপরে যুক্ত করেছি
BeeOnRope

ঝরঝরে। আমি আমার উত্তরটি একটি অতিরিক্ত আদিম সংস্করণ দিয়ে আপডেট করেছি যাতে কোনও বক্সিং এড়ানো উচিত।
ডোনাল্ড রাব

6

কোর জাভা ব্যবহার করে এটি সবচেয়ে সংক্ষিপ্ততম।

List<Integer> makeSequence(int begin, int end) {
  List<Integer> ret = new ArrayList(end - begin + 1);

  for(int i = begin; i <= end; i++, ret.add(i));

  return ret;  
}

3
আপনি এই লুপটি পরিবর্তন করে আরও কয়েকটি চরিত্রের শেভ করতে পারেন for(int i = begin; i <= end; ret.add(i++));:)
ভৌগানড্রয়েড

আমি সত্যিই নিশ্চিত নই যে ret.add(i)লুপ ইনক্রিমেন্টের জন্য অংশটি সরিয়ে নেওয়া এই "খাটো" করে তোলে। আমি মনে করি এই যুক্তি অনুসারে যদি আমি এটি সমস্ত লাইনে লিখে রাখি তবে এটি সংক্ষিপ্ত হবে :)
BeeOnRope

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

আমি উপরের উত্তরটির জন্য পারফরম্যান্স ফলাফলগুলি ক্ল্যাসিকআরলিস্ট লেবেল যুক্ত করেছি
BeeOnRope

3

আপনি পেয়ারা রেঞ্জ ব্যবহার করতে পারেন

আপনি SortedSetব্যবহার করে একটি পেতে পারেন

ImmutableSortedSet<Integer> set = Ranges.open(1, 5).asSet(DiscreteDomains.integers());
// set contains [2, 3, 4]

0

এটি সবচেয়ে সংক্ষিপ্ততম আমি খুঁজে পেতে পারি।

তালিকা সংস্করণ

public List<Integer> makeSequence(int begin, int end)
{
    List<Integer> ret = new ArrayList<Integer>(++end - begin);

    for (; begin < end; )
        ret.add(begin++);

    return ret;
}

অ্যারে সংস্করণ

public int[] makeSequence(int begin, int end)
{
    if(end < begin)
        return null;

    int[] ret = new int[++end - begin];
    for (int i=0; begin < end; )
        ret[i++] = begin++;
    return ret;
}

-2

এটি আপনার পক্ষে কাজ করতে পারে ....

void List<Integer> makeSequence(int begin, int end) {

  AtomicInteger ai=new AtomicInteger(begin);
  List<Integer> ret = new ArrayList(end-begin+1);

  while ( end-->begin) {

    ret.add(ai.getAndIncrement());

  }
  return ret;  
}

অ্যাটমিকআইন্টিজার ব্যবহার রিসোর্সের পক্ষে খুব ভারী, আমার পরীক্ষায় প্রায় দশবার ধীর। তবে এটি মাল্টিথ্রেডের জন্য সুরক্ষিত। শেষ <শুরু করা যাচাই করা হয়নি
cl-r

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