একটি স্ট্রিংবিল্ডারের শেষ চরিত্রটি সরান?


422

যখন আপনাকে কোনও সংগ্রহের মধ্য দিয়ে লুপ করতে হবে এবং একটি ডিলিমিটার দ্বারা পৃথক করা প্রতিটি ডেটার একটি স্ট্রিং তৈরি করতে হয়, আপনি সর্বদা শেষে অতিরিক্ত সীমানি দিয়ে শেষ করেন, যেমন

for (String serverId : serverIds) {
  sb.append(serverId);
   sb.append(",");
}

সার্ভার আইডি_1, সার্ভার আইডি 3, সার্ভার আইডি_3, যেমন কিছু দেয় ,

আমি স্ট্রিংবিল্ডারের শেষ চরিত্রটি মুছতে চাই (এটি রূপান্তর না করেই কারণ এই লুপটির পরেও আমার এটির দরকার আছে)।


11
যদি স্ট্রিংগুলিতে যোগ দিয়ে আপনি "স্ট্রিং কনটেনটেশন" অর্থ, এটি স্ট্রিংয়ের সংখ্যা এবং তার দৈর্ঘ্যের উপর নির্ভর করে। স্ট্রিং নির্মাতাকে ব্যবহার করা আরও কার্যকর যদি আপনি স্ট্রিং অপরিবর্তনীয় হওয়ায় তার আকার নির্বিশেষে অনেকগুলি স্ট্রিংয়ে হাতুড়ি হয়ে যাচ্ছেন। প্রতিবার আপনি যখন স্ট্রিংগুলি একত্রে সংযুক্ত করেন আপনি একটি নতুন ফলাফল স্ট্রিং তৈরি করছেন (যা সত্যই একটি চর অ্যারে)। স্ট্রিং বিল্ডারগুলি মূলত চরের একটি তালিকা যা আপনি টসস্ট্রিং () পদ্ধতিতে কল না করা পর্যন্ত অপরিবর্তনীয় স্ট্রিং হয়ে ওঠে না।
ডিসাইলেসিকানবোকো

4
আপনি জাভা 8 ব্যবহার করেন, তাহলে মাত্র ব্যবহার StringJoiner: stackoverflow.com/a/29169233/901641
ArtOfWarfare

উত্তর:


640

অন্যরা deleteCharAtপদ্ধতিটি নির্দেশ করেছেন , তবে এখানে আরও একটি বিকল্প পদ্ধতি রয়েছে:

String prefix = "";
for (String serverId : serverIds) {
  sb.append(prefix);
  prefix = ",";
  sb.append(serverId);
}

বিকল্পভাবে, পেয়ারাJoiner থেকে ক্লাসটি ব্যবহার করুন :)

জাভা 8 হিসাবে, StringJoinerস্ট্যান্ডার্ড জেআরই অংশ।


7
@ করোন্যাটাস: না, কারণ "" হ'ল কোনও চরিত্রের অনুপস্থিতি , একটি চরিত্র নয়।
জন স্কিটে

31
উপসর্গ কার্যকর করা হবে না = ","; প্রতিটি লুপ চক্র কর্মক্ষমতা প্রভাবিত করে?
হরিশ 10

21
@ হরিশ: সম্ভবত, একটি ক্ষুদ্র, সামান্য বিট - যদিও তা উল্লেখযোগ্য হওয়ার সম্ভাবনা খুব কমই।
জন স্কিটি

4
@ হরিশ - এবং সম্ভবত মোটেও নয়, যদি অপ্টিমাইজারটি প্রথম লুপ পুনরাবৃত্তিকে তালিকাভুক্ত করে।
স্টিফেন সি

6
এ্যাপাচি কমন্স পেয়ারা এর আরেকটি বিকল্প আছে Joinerতাদের মধ্যে খুব StringUtilscommons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)
GoRoS

419

আর একটি সহজ সমাধান হ'ল:

sb.setLength(sb.length() - 1);

আরও জটিল সমাধান:

উপরের সমাধানটি ধরে নিয়েছে যে sb.length() > 0... অপসারণের জন্য একটি "শেষ চরিত্র" রয়েছে। আপনি যদি এই অনুমান করতে না পারেন, এবং / বা অনুমানটি ভুল হলে আপনি যে ব্যাতিক্রমটি গ্রহণ করে তা মোকাবেলা করতে পারেন না, তবে প্রথমে স্ট্রিংবিল্ডারের দৈর্ঘ্য পরীক্ষা করে দেখুন; যেমন

// Readable version
if (sb.length() > 0) {
   sb.setLength(sb.length() - 1);
}

অথবা

// Concise but harder-to-read version of the above.
sb.setLength(Math.max(sb.length() - 1, 0));

23
খুব সুন্দর সমাধান। পারফরম্যান্স এবং সর্বনিম্ন কোডের উপরে সর্বনিম্ন প্রভাব :)
আলাইন ও'ডিয়া

186
if(sb.length() > 0){
    sb.deleteCharAt(sb.length() - 1);
}

33
এটি অত্যধিক উত্সাহিত হয় তবে এটি কার্যকর নয়, এটি একটি সিস্টেম.আরেকেপি করে। @ রোহিত রেড্ডি কোরাপোলু কী বলেছিলেন।
অ্যালিয়ানোস-

13
sb.length() == 0এটিও অনিরাপদ
ম্যাথিয়াস

এটি কী সুরোগেট জুটির চরিত্রে অভিনয় করে নিরাপদ?
রজারডপ্যাক

ধরে নিলাম যে শেষ চরিত্রটি কমা বিভাজক (উদাহরণ হিসাবে), তারপরে সার্গেটগুলি কোনও পার্থক্য রাখে না। যদি আপনার সাধারণকরণের প্রয়োজন হয় তবে separator.length()1 এর পরিবর্তে বিয়োগ করুন
স্টিফেন সি

61

জাভা 8 হিসাবে, স্ট্রিং ক্লাসের একটি স্ট্যাটিক পদ্ধতি রয়েছে join। প্রথম যুক্তি হ'ল একটি স্ট্রিং যা আপনি প্রতিটি জোড় স্ট্রিংয়ের মধ্যে চান এবং দ্বিতীয়টি একটি Iterable<CharSequence>(যা উভয় ইন্টারফেস, List<String>সুতরাং কাজ এর মতো কিছু So তাই আপনি এটি করতে পারেন:

String.join(",", serverIds);

জাভা 8-তে, আপনি নতুন StringJoinerক্লাসটি ব্যবহার করতে পারেন এমন পরিস্থিতিতে আপনি স্ট্রিংটি তৈরির উপাদানগুলির সম্পূর্ণ তালিকা রাখার আগে স্ট্রিং তৈরি শুরু করতে চান।


আপনি যদি কিছু মনে না করেন তবে আপনার জন্য এনভিএম সম্পাদিত, আমার মন্তব্যটিও সরিয়ে ফেলে
ইউজিন

@ ইউজিন - String.joinপরিবর্তে ফোকাস করার জন্য আমি উত্তরটি পুরোপুরি আবার লিখেছি StringJoiner
আর্টঅফ ওয়ারফেয়ার

37

কেবলমাত্র শেষ চরিত্রের উপস্থিতির অবস্থান পান।

for(String serverId : serverIds) {
 sb.append(serverId);
 sb.append(",");
}
sb.deleteCharAt(sb.lastIndexOf(","));

যেহেতু lastIndexOfএকটি বিপরীত অনুসন্ধান সম্পাদন করবে এবং আপনি জানেন যে এটি প্রথম চেষ্টাতেই পাওয়া যাবে, এখানে পারফরম্যান্স কোনও সমস্যা হবে না।

সম্পাদনা

যেহেতু আমি আমার উত্তরটি পেতে থাকি (ধন্যবাদ লোকেরা 😊), সে সম্পর্কে এটি মূল্যবান:

উপর জাভা 8 অনওয়ার্ড এটা ঠিক অধিক সহজপাঠ্য এবং ব্যবহার করা স্পষ্ট হবে StringJoiner । এটি একটি সরল বিভাজকের জন্য একটি পদ্ধতি এবং উপসর্গ এবং প্রত্যয় জন্য একটি ওভারলোড।

উদাহরণগুলি এখান থেকে নেওয়া: উদাহরণস্বরূপ

সাধারণ বিভাজক ব্যবহার করে উদাহরণ:

    StringJoiner mystring = new StringJoiner("-");    

    // Joining multiple strings by using add() method  
    mystring.add("Logan");  
    mystring.add("Magneto");  
    mystring.add("Rogue");  
    mystring.add("Storm");  

    System.out.println(mystring);

আউটপুট:

লোগান-ম্যাগনেটো-দুর্বৃত্ত-ঝড়

প্রত্যয় এবং উপসর্গ সহ উদাহরণ:

    StringJoiner mystring = new StringJoiner(",", "(", ")");    

    // Joining multiple strings by using add() method  
    mystring.add("Negan");  
    mystring.add("Rick");  
    mystring.add("Maggie");  
    mystring.add("Daryl");  

    System.out.println(mystring);

আউটপুট

(Negan, রিক, ম্যাগি, ড্যারিল)


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

34

এক্ষেত্রে,

sb.setLength(sb.length() - 1);

এটি কেবলমাত্র সর্বশেষ মানটি নির্ধারণ করে '\0'যেখানে শেষ অক্ষরটি মুছে ফেলা হয়System.arraycopy


1
setLengthকল সর্বশেষ মান কিছু বরাদ্দ করা হয় না। জাভা স্ট্রিং বাফারগুলি বাতিল / শূন্যের সমাপ্ত হয় না। আসলে, setLengthকেবল একটি lengthক্ষেত্র আপডেট করা হয় ।
স্টিফেন সি

@ রোহিত রেড্ডি কোরাপোলু: তবে arraycopy0 টি উপাদানগুলি অনুলিপি করা হয়েছে, তাই আমার ধারণা এটি অপরিবর্তিত হতে পারে।
maarartinus

2
যদি নতুন দৈর্ঘ্য আর্গুমেন্ট বর্তমান দৈর্ঘ্যের চেয়ে বড় বা সমান হয় তবে পর্যাপ্ত নাল অক্ষর ('\ u0000') যুক্ত করা হয় যাতে দৈর্ঘ্যটি নতুন দৈর্ঘ্যের আর্গুমেন্টে পরিণত হয়। কোন ঘটনা না।
fglez

12

সঙ্গে Java-8তোমাদের স্ট্যাটিক পদ্ধতি ব্যবহার করতে পারেন Stringবর্গ,

String#join(CharSequence delimiter,Iterable<? extends CharSequence> elements)


public class Test {

    public static void main(String[] args) {

        List<String> names = new ArrayList<>();
        names.add("James");
        names.add("Harry");
        names.add("Roy");
        System.out.println(String.join(",", names));
    }
}

আউটপুট

James,Harry,Roy

11

আরেকটি বিকল্প

for(String serverId : serverIds) {
   sb.append(",");
   sb.append(serverId); 
}
sb.deleteCharAt(0);

2
শেষের চরটি অপসারণের চেয়ে ভাল হওয়া উচিত কারণ এর জন্য আকারের গণনা প্রয়োজন। প্রথম চরটি অপসারণ না করলে ডেটা চারপাশে সরানো হয় ...
স্লট করুন

8

অন্যথা,

StringBuilder result = new StringBuilder();
for(String string : collection) {
    result.append(string);
    result.append(',');
}
return result.substring(0, result.length() - 1) ;

আপনি একটি "যোগ করতে পারেন হিসাবে ব্যবহারযোগ্য।" শেষে.
artfullyContrived

6
StringBuilder sb = new StringBuilder();
sb.append("abcdef");
sb.deleteCharAt(sb.length() - 1);
assertEquals("abcde",sb.toString());
// true

5

তবুও অন্য বিকল্প:

public String join(Collection<String> collection, String seperator) {
    if (collection.isEmpty()) return "";

    Iterator<String> iter = collection.iterator();
    StringBuilder sb = new StringBuilder(iter.next());
    while (iter.hasNext()) {
        sb.append(seperator);
        sb.append(iter.next());
    }

    return sb.toString();
}

3

TextUtils.isEmpty prefixব্যবহারের পুনর্নির্মাণ (কর্মক্ষমতা প্রভাবিত) এড়াতে:

            String prefix = "";
            for (String item : list) {
                sb.append(prefix);
                if (TextUtils.isEmpty(prefix))
                    prefix = ",";
                sb.append(item);
            }

টেস্টUtils কোন ধরণের প্যাকেজের সাথে সম্পর্কিত?
মার্কাস

@ মারকাস অ্যান্ড্রয়েড.টেক্সট.টেক্সট ইউটিলস
নিকউনুখেখ

1

আপনি আপনার উত্পন্ন পাঠ্য থেকে শেষ চরিত্রটি সরিয়ে না দেওয়ার পরিবর্তে 'যোগদানকারী' শ্রেণিটি ব্যবহার করার চেষ্টা করতে পারেন;

                List<String> textList = new ArrayList<>();
                textList.add("text1");
                textList.add("text2");
                textList.add("text3");

                Joiner joiner = Joiner.on(",").useForNull("null");
                String output = joiner.join(textList);

               //output : "text1,text2,text3"

1

আমি নীচের মতো কিছু করছি:

    StringBuilder stringBuilder = new StringBuilder();
    for (int i = 0; i < value.length; i++) {
        stringBuilder.append(values[i]);
        if (value.length-1) {
            stringBuilder.append(", ");
        }
    }

0

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

for(String serverId : serverIds) {
   sb.append(",");
   sb.append(serverId); 
}

String resultingString = "";
if ( sb.length() > 1 ) {
    resultingString = sb.substring(1);
}

1
আচ্ছা বুঝলাম. আপনি স্ট্রিংবিল্ডারে স্ট্রিংকে স্ট্রিং নয় calling
স্টিফেন সি

কিন্তু যাই হোক, এই 2010 থেকে জাকি এর সমাধানে শুধু একটি ছোট বৈচিত্র হয়
স্টিফেন সি

0

আমি ব্যক্তিগতভাবে একটি ব্যাকস্পেস অক্ষর যুক্ত করতে চাই (বা আরও দীর্ঘতর "জন্য আরও কিছু" এর জন্য) শেষে:

for(String serverId : serverIds) {
    sb.append(serverId);
    sb.append(",");
}

sb.append('\b');

মনে রাখবেন যে এতে সমস্যা রয়েছে:

  • \bপরিবেশের উপর নির্ভর করে কীভাবে প্রদর্শিত হয়,
  • length()এর Stringবিষয়বস্তু "দৃশ্যমান" অক্ষরের দৈর্ঘ্য থেকে আলাদা হতে পারে

যখন \bঠিক আছে এবং দৈর্ঘ্যের কোনও কনসোলে লগইন করার মতো বিষয় নেই তবে এটি আমার পক্ষে যথেষ্ট ভাল বলে মনে হচ্ছে।


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