জাভাতে লুপের জন্য বর্ধিত সর্বশেষ পুনরাবৃত্তি


140

লুপটি শেষবারের জন্য পুনরাবৃত্তি করছে কিনা তা নির্ধারণ করার কোনও উপায় আছে কি? আমার কোডটি এরকম কিছু দেখাচ্ছে:

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();

for(int i : array)
{
    builder.append("" + i);
    if(!lastiteration)
        builder.append(",");
}

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


1
হ্যাঁ! মজার বিষয়, আমি ঠিক একই প্রশ্নটি জিজ্ঞাসা করতে চেয়েছিলাম!
ফিলিহো

একই ধরণের প্রশ্ন ফিরে আসে (এবং তা হবে)। এখন যদি কোনও উপাদানটির আলাদা চিকিত্সার প্রয়োজন হয় তবে আপনি কেন একটি লুপ তৈরি করতে চান? stackoverflow.com/questions/156650/...
xtofl

যেহেতু আপনার একটি নির্দিষ্ট অ্যারে রয়েছে তবে কেন উন্নত ব্যবহার করবেন? (int i = 0; i <
অ্যারে. দৈর্ঘ্য

উত্তর:


223

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

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();

for (int i : array) {
    if (builder.length() != 0) {
        builder.append(",");
    }
    builder.append(i);
}

এটি সম্পর্কে দুর্দান্ত জিনিসটি হ'ল এটি যে কোনওটির সাথে কাজ করবে Iterable- আপনি সর্বদা জিনিসগুলি সূচী করতে পারবেন না। ("কমা যুক্ত করুন এবং এরপরে এটি সরিয়ে ফেলুন") আপনি যখন স্ট্রিংবিল্ডার সত্যিই ব্যবহার করছেন তখন একটি দুর্দান্ত পরামর্শ - তবে এটি স্ট্রিমগুলিতে লেখার মতো জিনিসগুলির পক্ষে কাজ করে না exact যদিও সম্ভবত এই সঠিক সমস্যার জন্য এটি সর্বোত্তম পন্থা। )


2
ভাল প্যাটার্ন, তবে বিল্ডার.লেন্থ ()! = 0 ভঙ্গুর - আপনার লুপের আগে বাফারে কিছু যুক্ত হয়ে (শর্তাধীন!) কল্পনা করুন। পরিবর্তে, একটি isFirstবুলিয়ান পতাকা ব্যবহার করুন । বোনাস: দ্রুত।
জেসন কোহেন

2
@ জেসন: আমি অবশ্যই "ইসফার্স্ট" প্যাটার্নটি ব্যবহার করি যেখানে নির্মাতা প্রথম পুনরাবৃত্তিতে খালি হবে না। যাইহোক, যখন এটির প্রয়োজন হয় না, এটি আমার অভিজ্ঞতাতে প্রয়োগের জন্য একটি পর্যাপ্ত পরিমাণে ফোলা যোগ করে।
জন স্কিটি

3
@ লিভারপুল (ইত্যাদি): 1000 অপ্রয়োজনীয় চেকগুলি পারফরম্যান্সে কোনও উল্লেখযোগ্য প্রভাব ফেলার খুব কম সম্ভাবনা। আমি সমানভাবে বাতলান হতে পারে দীণার সমাধান যোগ করে অতিরিক্ত অক্ষর পারে StringBuilder কারণ প্রসারিত আছে, (চলছে) সঙ্গে চূড়ান্ত স্ট্রিং এর আকার দ্বিগুন
জন স্কিট

2
অপ্রয়োজনীয় বাফার স্পেস। তবে, গুরুত্বপূর্ণ বিষয়টি পঠনযোগ্যতা। আমি আমার সংস্করণটি দিনার চেয়ে বেশি পঠনযোগ্য বলে খুঁজে পেয়েছি। যদি আপনি বিপরীত উপায় অনুভব করেন, তবে তা ঠিক আছে। আমি কেবল কোনও বাধা খুঁজে পাওয়ার পরে অপ্রয়োজনীয় "ifs" এর পারফরম্যান্স প্রভাবটি বিবেচনা করব।
জন স্কিটি

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

145

এটি করার আরেকটি উপায়:

String delim = "";
for (int i : ints) {
    sb.append(delim).append(i);
    delim = ",";
}

আপডেট: জাভা 8 এর জন্য আপনার এখন সংগ্রাহক রয়েছে


1
আমার অনুরূপ উত্তরটি মুছতে হয়েছিল - এটি আমাকে অন্য উত্তরগুলিতে আরও যত্ন সহকারে দেখার আগে পোস্ট না করা শিখবে।
মাইকেল বারার

1
আরও মনে রাখবেন যে এটি রবার্ট পলসন আরও একটি মন্তব্য থ্রেডে উল্লিখিত সম্ভাব্য সমস্যাটি পরিচালনা করে - অ্যারে মানগুলি সংযুক্ত করার পরে এই কৌশলটি স্ট্রিংবিল্ডার খালি থাকার উপর নির্ভর করে না।
মাইকেল বার বার

1
কোডটি আরও স্লট / ঝরঝরে / মজাদার হলেও এটি যদি সংস্করণটির চেয়ে কম স্পষ্ট হয়। সর্বদা আরও স্পষ্ট / পঠনযোগ্য সংস্করণ ব্যবহার করুন।
বিল কে

8
@ বিল: এটি একটি কঠোর এবং দ্রুত নিয়ম হিসাবে দুর্দান্ত নয়; এমন সময় আছে যেখানে 'চালাক' সমাধানটি "আরও সঠিক" সমাধান হয়। আরও উল্লেখযোগ্য বিষয়, আপনি কি সত্যিই জানেন যে এই সংস্করণটি পড়া কঠিন? যেভাবেই কোনও রক্ষণাবেক্ষণকারীকে এটির মাধ্যমে পদক্ষেপ নেওয়া দরকার - আমি মনে করি না পার্থক্যটি উল্লেখযোগ্য।
গ্রেগ কেস

আপনি অন্যান্য সিস্টেমগুলিতে যেমন ফাইল সিস্টেমে রাইটিং কল লেখেন এটি কাজ করে। ভাল ধারণা.
টাক্সমান

39

সর্বদা সংযুক্ত করা সহজ হতে পারে। এবং তারপরে, যখন আপনি আপনার লুপটি সম্পন্ন করবেন, কেবল চূড়ান্ত অক্ষরটি সরিয়ে ফেলুন। টনস কম কন্ডিশনাল সেভাবেও।

আপনি সূচক সহ StringBuilderএর ব্যবহার করতে পারেনdeleteCharAt(int index)length() - 1


5
এই সমস্যার সর্বাধিক দক্ষ সমাধান। +1 টি।
রিয়েল লাল

9
সম্ভবত এটি আমি, তবে আমি সত্যটি পছন্দ করি না যে আপনি সবেমাত্র যুক্ত কিছু আপনি মুছে
ফেলছেন

2
ফোর্তেগা: আমি প্রতিবার এমন কিছু যাচাই করতে পছন্দ করি না যা আমি 99% বার করব। দিনাহ বা এসব্লুন্ডির সমাধানটি প্রয়োগ করা আরও যৌক্তিক (এবং এটি দ্রুত) বলে মনে হচ্ছে।
মহিষ 14

1
আমার মতে সর্বাধিক মার্জিত সমাধান। ধন্যবাদ!
চার্লস মরিন

32

হয়ত আপনি কাজের জন্য ভুল সরঞ্জাম ব্যবহার করছেন।

এটি আপনি যা করছেন তার চেয়ে বেশি ম্যানুয়াল তবে এটি কিছুটা "মার্চ স্কুল" না হলে আরও মার্জিত a

 StringBuffer buffer = new StringBuffer();
 Iterator iter = s.iterator();
 while (iter.hasNext()) {
      buffer.append(iter.next());
      if (iter.hasNext()) {
            buffer.append(delimiter);
      }
 }


14

আরেকটি সমাধান (সম্ভবত সবচেয়ে দক্ষ)

    int[] array = {1, 2, 3};
    StringBuilder builder = new StringBuilder();

    if (array.length != 0) {
        builder.append(array[0]);
        for (int i = 1; i < array.length; i++ )
        {
            builder.append(",");
            builder.append(array[i]);
        }
    }

এটি অ্যারে খালি না হওয়ার উপর নির্ভর করে এটি একটি প্রাকৃতিক সমাধান।
অরকিমিড

5
@ অর্মসিড: যদি অ্যারেটি খালি থাকে তবে এটি এখনও সঠিক আউটপুট দেয় - একটি খালি স্ট্রিং। আমি নিশ্চিত যে আপনার বক্তব্য কি।
এডি


6

সুস্পষ্ট লুপগুলি সর্বদা অন্তর্ভুক্তগুলির চেয়ে ভাল কাজ করে।

builder.append( "" + array[0] );
for( int i = 1; i != array.length; i += 1 ) {
   builder.append( ", " + array[i] );
}

আপনি যদি শূন্য দৈর্ঘ্যের অ্যারে নিয়ে কাজ করছেন কেবলমাত্র যদি আপনার বিবৃতিতে পুরো জিনিসটি মুড়ে ফেলা উচিত।


আমি এই পদ্ধতির পছন্দ করি কারণ এটি প্রতিটি পুনরাবৃত্তির অকারণে কোনও পরীক্ষা করে না। আমি কেবল যুক্ত করতে চাই যে নির্মাতা সরাসরি পূর্ণসংখ্যাগুলি সংযোজন করতে পারে তাই "+ ইনট, কেবল সংযোজন (অ্যারে [0]) ব্যবহার করার দরকার নেই।
জোশ

আপনার অ্যারে কমপক্ষে একটি উপাদান রয়েছে কিনা তা নিশ্চিত করতে পুরো লটের চারপাশে আরও একটি প্রয়োজন।
টম লিজ

2
কেন প্রত্যেকে স্ট্রিং কনটেন্টেশন সহ উদাহরণগুলি ব্যবহারের মধ্যে অন্তর্ভুক্ত রাখবে? "," + এক্স নতুন স্ট্রিংবিল্ডারে সংকলন করে (",") appপেনড (এক্স) to স্ট্রিং () ...
জন গার্ডনার

@ জোশ এবং @ জোহান: ঠিক N00b উদাহরণ অনুসরণ করছেন। একবারে খুব বেশি জিনিস পরিচয় করিয়ে দিতে চাই না। তবে আপনার বক্তব্যটি খুব ভাল।
এস .লট

@ টম: ঠিক আছে। আমি মনে করি আমি ইতিমধ্যে এটি বলেছি। কোনও সম্পাদনের প্রয়োজন নেই।
এস .লট

4

আপনি যদি এটি কোনও ক্লাসিক সূচক লুপে রূপান্তর করেন তবে হ্যাঁ।

অথবা আপনি শেষ কমাটি শেষ করার পরে মুছতে পারেন। তাই ভালো:

int[] array = {1, 2, 3...};
StringBuilder

builder = new StringBuilder();

for(int i : array)
{
    builder.append(i + ",");
}

if(builder.charAt((builder.length() - 1) == ','))
    builder.deleteCharAt(builder.length() - 1);

আমি, আমি কেবল কমন্স-ল্যাংStringUtils.join() থেকে ব্যবহার করি ।


3

আপনার ক্লাস বিভাজক প্রয়োজন ।

Separator s = new Separator(", ");
for(int i : array)
{
     builder.append(s).append(i);
}

শ্রেণি বাস্তবায়ন Separatorসরাসরি এগিয়ে। এটি এমন একটি স্ট্রিং জড়িয়ে দেয় toString()যা প্রথম কল ব্যতীত প্রতিটি কলগুলিতে ফিরে আসে, যা খালি স্ট্রিং দেয়।


3

Java.util.Aststract Collections.toString () এর উপর ভিত্তি করে, ডিলিমিটারটি এড়ানোর জন্য তা তাড়াতাড়ি প্রস্থান করে।

StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
for (;;) {
  buffer.append(iter.next());
  if (! iter.hasNext())
    break;
  buffer.append(delimiter);
}

এটি দক্ষ এবং মার্জিত, তবে অন্যান্য উত্তরগুলির মতো স্ব-স্পষ্ট নয়।


আপনি কখন তাড়াতাড়ি রিটার্ন অন্তর্ভুক্ত করতে ভুলে গিয়েছিলেন (! i.hasNext()), যা সামগ্রিক পদ্ধতির দৃust়তার একটি গুরুত্বপূর্ণ অঙ্গ। (এখানে অন্যান্য সমাধানগুলি খালি সংগ্রহগুলি দুর্দান্তভাবে পরিচালনা করে, তাই আপনারও উচিত! :)
মাইক ক্লার্ক

3

এখানে একটি সমাধান:

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
bool firstiteration=true;

for(int i : array)
{
    if(!firstiteration)
        builder.append(",");

    builder.append("" + i);
    firstiteration=false;
}

প্রথম পুনরাবৃত্তি জন্য দেখুন :)  


3

টুলকিট হিসাবে উল্লিখিত হয়েছে, জাভা 8-এ এখন আমাদের সংগ্রাহক রয়েছে । কোডটি দেখতে কেমন হবে তা এখানে:

String joined = array.stream().map(Object::toString).collect(Collectors.joining(", "));

আমি মনে করি এটি আপনি যা খুঁজছেন ঠিক তেমনই করে এবং এটি এমন একটি প্যাটার্ন যা আপনি অন্যান্য অনেক কিছুর জন্য ব্যবহার করতে পারেন।


1

তবুও অন্য একটি বিকল্প।

StringBuilder builder = new StringBuilder();
for(int i : array)
    builder.append(',').append(i);
String text = builder.toString();
if (text.startsWith(",")) text=text.substring(1);

অন্যান্য প্রশ্নে আমি তারতম্য করেছি
13ren

1

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

সম্পাদনা করুন : আসল সমাধানটি সঠিক, তবে মন্তব্য অনুসারে অপ-অনুকূল নয়। দ্বিতীয়বার চেষ্টা করা হচ্ছে:

    int[] array = {1, 2, 3};
    StringBuilder builder = new StringBuilder();
    for (int i = 0 ;  i < array.length; i++)
           builder.append(i == 0 ? "" : ",").append(array[i]); 

আপনি অ্যারে এবং স্ট্রিংবিল্ডার ঘোষণা সহ কোডের 4 টি লাইনে যান।


তবে আপনি প্রতিটি পুনরাবৃত্তিতে একটি নতুন স্ট্রিংবিল্ডার তৈরি করছেন (+ অপারেটরকে ধন্যবাদ)।
মাইকেল মায়ার্স

হ্যাঁ, আপনি যদি বাইটোকোডটি দেখুন তবে আপনি ঠিক বলেছেন। আমি বিশ্বাস করতে পারি না এত সহজ প্রশ্ন এত জটিল হয়ে উঠতে পারে। আমি ভাবছি যে সংকলকটি এখানে অনুকূলিত করতে পারে wonder
জুলিয়ান চস্তং

2 য় প্রদত্ত, আশা করি আরও ভাল সমাধান।
জুলিয়েন চস্তং

1

এই ফলাফলগুলি সহ আমি এখানে এসএসসিসিই একটি বেঞ্চমার্ক দৌড়েছি (আমার কী প্রয়োগ করতে হবে তার সাথে সম্পর্কিত):

elapsed time with checks at every iteration: 12055(ms)
elapsed time with deletion at the end: 11977(ms)

অন্তত আমার উদাহরণস্বরূপ, প্রতি পুনরাবৃত্তির এ চেক কুঁদন লক্ষণীয়ভাবে দ্রুততর বিশেষত তথ্য বিবেকী ভলিউম জন্য নয়, কিন্তু এটি হল দ্রুত।

import java.util.ArrayList;
import java.util.List;


public class TestCommas {

  public static String GetUrlsIn(int aProjectID, List<String> aUrls, boolean aPreferChecks)
  {

    if (aPreferChecks) {

      StringBuffer sql = new StringBuffer("select * from mytable_" + aProjectID + " WHERE hash IN ");

      StringBuffer inHashes = new StringBuffer("(");
      StringBuffer inURLs = new StringBuffer("(");

      if (aUrls.size() > 0)
      {

      for (String url : aUrls)
      {

        if (inHashes.length() > 0) {
        inHashes.append(",");
        inURLs.append(",");
        }

        inHashes.append(url.hashCode());

        inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"");//.append(",");

      }

      }

      inHashes.append(")");
      inURLs.append(")");

      return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString();
    }

    else {

      StringBuffer sql = new StringBuffer("select * from mytable" + aProjectID + " WHERE hash IN ");

      StringBuffer inHashes = new StringBuffer("(");
      StringBuffer inURLs = new StringBuffer("(");

      if (aUrls.size() > 0)
      {

      for (String url : aUrls)
      {
        inHashes.append(url.hashCode()).append(","); 

        inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"").append(",");
      }

      }

      inHashes.deleteCharAt(inHashes.length()-1);
      inURLs.deleteCharAt(inURLs.length()-1);

      inHashes.append(")");
      inURLs.append(")");

      return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString();
    }

  }

  public static void main(String[] args) { 
        List<String> urls = new ArrayList<String>();

    for (int i = 0; i < 10000; i++) {
      urls.add("http://www.google.com/" + System.currentTimeMillis());
      urls.add("http://www.yahoo.com/" + System.currentTimeMillis());
      urls.add("http://www.bing.com/" + System.currentTimeMillis());
    }


    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 300; i++) {
      GetUrlsIn(5, urls, true);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("elapsed time with checks at every iteration: " + (endTime-startTime) + "(ms)");

    startTime = System.currentTimeMillis();
    for (int i = 0; i < 300; i++) {
      GetUrlsIn(5, urls, false);
    }
    endTime = System.currentTimeMillis();
    System.out.println("elapsed time with deletion at the end: " + (endTime-startTime) + "(ms)");
  }
}

1
দয়া করে আপনার নিজস্ব বেঞ্চমার্কগুলি রোল করবেন না এবং ওপেনজেডিকেগুলির নিজের মাইক্রো বেঞ্চমার্কিং হারনেস (জেএমএইচ) ব্যবহার করবেন না । এটি আপনার কোডটি উষ্ণ করবে এবং সবচেয়ে সমস্যাযুক্ত সমস্যাগুলি এড়াবে।
রেনি

0

আর একটি পদ্ধতি হ'ল অ্যারের দৈর্ঘ্য (যদি উপলব্ধ থাকে) একটি পৃথক ভেরিয়েবলে সঞ্চিত থাকে (প্রতিটি বারের দৈর্ঘ্যের পুনরায় পরীক্ষার চেয়ে আরও দক্ষ)। তারপরে আপনি চূড়ান্ত কমা যুক্ত করবেন কি না তা নির্ধারণ করতে আপনার সূচিটিকে সেই দৈর্ঘের সাথে তুলনা করতে পারেন।

সম্পাদনা: প্রতিটি পুনরাবৃত্তিতে শর্তসাপেক্ষে পরীক্ষা করা ব্যতিরেকে একটি চূড়ান্ত অক্ষর (যা স্ট্রিং কপির কারণ হতে পারে) অপসারণের পারফরম্যান্স ব্যয়কে অন্য বিবেচনা বিবেচনা করা হচ্ছে।


চূড়ান্ত অক্ষর অপসারণের কারণে স্ট্রিং অনুলিপি তৈরি করা উচিত নয়। স্ট্রিংবুফারের ডিলেট / ডিলিটচ্যার্যাট পদ্ধতিগুলি শেষ পর্যন্ত সিস্টেম বর্গের অভিন্ন উত্স এবং গন্তব্য অ্যারেগুলির মধ্যে নিম্নলিখিত পদ্ধতিটিকে কল করে: সিস্টেম -> পাবলিক স্ট্যাটিক নেটিভ শূন্য অ্যারেকপি (অবজেক্ট এসসিআর, ইনসিআরসিপিপোস, অবজেক্ট ডেস্ট, ইন ডেসটপোস, ইন্ট দৈর্ঘ্য);
মহিষ 14

0

যদি আপনি কেবল একটি কমা বিস্মৃত অ্যারে রূপান্তর করেন তবে অনেক ভাষার ঠিক এর জন্য একটি জয়েন্ট ফাংশন থাকে। এটি প্রতিটি উপাদানগুলির মধ্যে একটি ডিলিমিটার সহ একটি স্ট্রিতে একটি অ্যারে পরিণত করে।


0

এই ক্ষেত্রে এটি শেষ পুনরাবৃত্তি কিনা তা সত্যিই জানার দরকার নেই। এটি সমাধান করার অনেক উপায় রয়েছে ways একটি উপায় হবে:

String del = null;
for(int i : array)
{
    if (del != null)
       builder.append(del);
    else
       del = ",";
    builder.append(i);
}

0

এখানে দুটি বিকল্প পথ:

1: অ্যাপাচি কমন্স স্ট্রিং ইউটিলস

2: একটি বুলিয়ান কল করুন first, সত্য হিসাবে সেট করুন। প্রতিটি পুনরাবৃত্তিতে, যদি firstএটি মিথ্যা হয়, আপনার কমা যুক্ত করুন; এর পরে, মিথ্যাতে সেট firstকরুন।


1) লিঙ্কটি মারা গেছে 2)
বাফেলো

0

যেহেতু এটি একটি নির্দিষ্ট অ্যারে, এর জন্য বর্ধিত এড়াতে সহজ হবে ... অবজেক্টটি যদি সংগ্রহ হয় তবে একটি পুনরুক্তি করা সহজ হবে।

int nums[] = getNumbersArray();
StringBuilder builder = new StringBuilder();

// non enhanced version
for(int i = 0; i < nums.length; i++){
   builder.append(nums[i]);
   if(i < nums.length - 1){
       builder.append(",");
   }   
}

//using iterator
Iterator<int> numIter = Arrays.asList(nums).iterator();

while(numIter.hasNext()){
   int num = numIter.next();
   builder.append(num);
   if(numIter.hasNext()){
      builder.append(",");
   }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.