2011-11-24 5 views
26

एक सूचीअल्पविरामों से जावा में एक सूची <String> में शामिल होने और "और"

List<String> l = new ArrayList<String>(); 
l.add("one"); 
l.add("two"); 
l.add("three"); 

मैं एक विधि है यह देखते हुए

String join(List<String> messages) { 
     if (messages.isEmpty()) return ""; 
     if (messages.size() == 1) return messages.get(0); 
     String message = ""; 
     message = StringUtils.join(messages.subList(0, messages.size() -2), ", "); 
     message = message + (messages.size() > 2 ? ", " : "") + StringUtils.join(messages.subList(messages.size() -2, messages.size()), ", and "); 
     return message; 
    } 

जो, एल के लिए, पैदा करता है "एक, दो, और तीन" । मेरा प्रश्न है, वहाँ एक विधि मानक (अपाचे-कॉमन्स) है कि एक ही ?, जैसे

WhatEverUtils.join(l, ", ", ", and "); 

स्पष्ट करने के लिए करता है। मेरी समस्या इस विधि को काम करने के लिए नहीं मिल रही है। यह वैसे ही काम करता है जैसा मैं चाहता हूं, यह परीक्षण किया गया है और सब ठीक है। मेरी समस्या यह है कि मुझे कुछ अपाचे-कॉमन्स-जैसे मॉड्यूल नहीं मिल सका जो ऐसी कार्यक्षमता लागू करता है। जो मुझे आश्चर्यचकित करता है, क्योंकि मैं इसकी आवश्यकता के लिए पहली नहीं हो सकता।

लेकिन तब शायद हर किसी बस

StringUtils.join(l, ", ").replaceAll(lastCommaRegex, ", and"); 
+0

मुझे नहीं लगता कि ऐसी ओपन सोर्स लाइब्रेरी है, लेकिन मैं संसाधन बंडलों का उपयोग करने की सलाह देता हूं क्योंकि सभी भाषाएं अंग्रेजी शब्द "और" का उपयोग नहीं करती हैं। –

+0

@ स्लीपसेट, आप ज्ञात पुस्तकालय से कुछ शामिल क्यों नहीं करते हैं और इसे थोड़ा सा संशोधित करते हैं? ध्यान दें कि "और" अंग्रेजी शब्द है, इसलिए यदि ऐसी लाइब्रेरी मौजूद होगी, तो इसमें बहु भाषाएं – smas

+0

का समर्थन करना पड़ सकता था, शायद मैं अस्पष्ट हो सकता था, लेकिन मैंने अपने प्रश्न में जो तरीका दिखाया है, मैंने लिखा है, और यह वैसे ही काम करता है जैसा मैं चाहता हूं। – slipset

उत्तर

13

मैं इस उद्देश्य के लिए गूगल संग्रह का उपयोग कर की तरह काम किया है। स्वच्छ और बहुत उपयोगी:

Joiner.on(",").join(myList) 

कोड इस तरह बार-बार लिखा गया है और यदि आप अपने विशिष्ट कार्यान्वयन तर्क को लागू करने को मुक्त कर दिया जाना चाहिए।

आप Maven उपयोग करते हैं, निर्भरता इसके साथ:

<dependency> 
    <groupId>com.google.collections</groupId> 
    <artifactId>google-collections</artifactId> 
    <version>1.0</version> 
</dependency> 

यह अन्य अद्भुत शांत का एक समूह भी सुविधाओं है!

संपादित करें: पूर्णता के लिए, यह "एक, दो, और तीन" सूची का उत्पादन करेगा।

List<String> originalList = Arrays.asList("one", "two", "three"); 
Joiner.on(", ").join(originalList.subList(0, originalList.size() - 1)) 
    .concat(", and ").concat(originalList.get(originalList.size() - 1)); 
+2

बस एफवाईआई: गुवा (http://code.google.com/p/guava-libraries/) के पक्ष में Google संग्रह को बहिष्कृत कर दिया गया है जो पूरी तरह से पीछे संगत सुपरसैट है। –

+0

काफी सही .. मैं इसके बारे में भूल गया। Maven निर्भरता अगर कोई रुचि रखता है: com.google.guava अमरूद 10.0.1

+1

मैं नहीं दिख रहा है यही कारण है कि आप के साथ जवाब downvoting रहे तरीका है जिसके उत्पादन में शामिल होने: "एक , दो तीन"। क्या आप चाहते हैं कि किसी भी स्ट्रिंग, या कुछ समान द्वारा अंतिम अल्पविराम को प्रतिस्थापित करना इतना कठिन है ?! यह 100% ठीक उत्तर है जो @ स्लीपसेट संभावित दिशा प्रदान करता है जो उसकी समस्या का समाधान कर सकता है। – smas

1

मैं किसी भी अपाचे स्ट्रिंग योजक कि शामिल हो गए स्ट्रिंग में and जोड़ने का समर्थन कर सकते हैं पता नहीं है।

यहाँ एक अपरीक्षित कोड है कि तुम क्या पूछा क्या करेंगे है:

public static String join(String separator, List<String> mList, boolean includeAndInText) { 
    StringBuilder sb = new StringBuilder(); 
    int count = 0; 

    for (String m: mList) { 
     if (includeAndInText && (count + 1 != mList.size())) { 
      sb.append (" and "); 
     } 

     sb.append(m); 
     count++; 
     if (count < mList.size()) { 
      sp.append(separator); 
     }  
    } 

    return sb.toString(); 
} 
+0

क्षमा करें, लेकिन मुझे नहीं लगता कि यह इस समस्या का सबसे अच्छा तरीका है। आईएमओ हमें कुछ ऐसा करना चाहिए जो मौजूद है (उदा। अपाचे से जुड़ें) और इसे "और", "या" या कुछ जो हमें उम्मीद है, प्राप्त करने के लिए थोड़ा सा संशोधित करें। – smas

+0

@smas, ठीक है, मैं असहमत हूं। आपकी ** केवल ** आवश्यकता के अनुसार मौजूदा पुस्तकालय को बदलना एक स्पष्ट विकल्प नहीं है (और मुझे विश्वास नहीं है) आप अपाचे में अपना परिवर्तन करेंगे। इसके अलावा, यदि 'स्ट्रिंगउल्ट्स' का एक और संस्करण जारी हो जाता है, तो आपको इसे बनाए रखना होगा और यह सुनिश्चित करना होगा कि आपका परिवर्तन प्रभावित नहीं हुआ है (हटाया गया है)।मैं कहता हूं, पुस्तकालय कार्यान्वयन एएस-आईएस छोड़ दो और अपनी खुद की उपयोगिता वर्ग लिखें। –

+1

मैं भी diagree। व्यवसायिक दुनिया में स्ट्रिंगयूटिल जैसे प्रसिद्ध पुस्तकालयों का उपयोग अक्सर पहिया को पुनर्निर्मित करने से बचने के लिए किया जाता है। यदि आप कुछ परिवर्तनों से अवगत हैं, तो आप इकाई परीक्षण लिखते हैं। इस मामले के लिए लेखन केवल अपने आप में शामिल हो क्योंकि "और" समय, धन और वस्तु उन्मुख प्रोग्रामिंग शैली की बर्बादी होनी चाहिए। – smas

11

क्या से join के बारे में: org.apache.commons.lang.StringUtils

उदाहरण:

StringUtils.join(new String[] { "one", "two", "three" }, ", "); // one, two, three 

करवाने के लिए "और" या ", और "आप अंतिम अल्पविराम को प्रतिस्थापित कर सकते हैं।

+0

वह ओपी के अनुरोध के रूप में '", दो, और तीन "का उत्पादन नहीं कर रहा है। ध्यान दें: वह अपने प्रश्न –

+0

@ लुकास में उस 'शामिल' विधि का उपयोग कर रहा है, लेकिन आप अंतिम अल्पविराम को प्रतिस्थापित कर सकते हैं, है ना? मुझे लाइब्रेरी रखने का अर्थ नहीं दिखता है जो मेरे लिए "और" जुड़ने की विधि में जोड़ता है। – smas

+0

एफवाईआई - मैंने ऐसा करने के लिए अतिरिक्त तरीकों को शामिल करने का अनुरोध करने के लिए https://issues.apache.org/jira/browse/LANG-1037 उठाया है। मैं कोशिश करूंगा और इसे अगले रिलीज में लागू कर दूंगा। –

3

अन्य उत्तर "अंतिम अल्पविराम को बदलने" के बारे में बात करते हैं, जो कि अंतिम अवधि में अल्पविराम के मामले में सुरक्षित नहीं है।

एक पुस्तकालय का उपयोग करने के बजाय, आप बस JDK कोड में से एक (लंबी यद्यपि) लाइन का उपयोग कर सकते हैं:

public static String join(List<String> msgs) { 
    return msgs == null || msgs.size() == 0 ? "" : msgs.size() == 1 ? msgs.get(0) : msgs.subList(0, msgs.size() - 1).toString().replaceAll("^.|.$", "") + " and " + msgs.get(msgs.size() - 1); 
} 

इस कोड को सभी बढ़त मामलों से निपटने का live demo देखें।

public static String join(List<String> msgs) { 
    int size = msgs == null ? 0 : msgs.size(); 
    return size == 0 ? "" : size == 1 ? msgs.get(0) : msgs.subList(0, --size).toString().replaceAll("^.|.$", "") + " and " + msgs.get(size); 
} 
7

जावा 8 के साथ, आप joiners साथ धाराओं का उपयोग कर सकते हैं:


FYI करें, यहाँ एक अधिक पठनीय दो लाइनर है।

Collection<String> strings; 
... 
String commaDelimited = strings.stream().collect(Collectors.joining(",")); 
// use strings.parallelStream() instead, if you think 
// there are gains to be had by doing fork/join 
21

जावा 8 में आप निम्नलिखित की तरह String.join() उपयोग कर सकते हैं:

Collection<String> elements = ....; 
String result = String.join(", ", elements); 
0

अंग्रेजी में व्याकरण उत्पादन का उत्पादन करने के लिए 3 मामलों जब स्ट्रिंग की एक सूची श्रृंखलाबद्ध विचार करने के लिए देखते हैं:

  1. "ए"

  2. "ए और बी"

  3. "ए, बी, और सी

यह नीचे की तरह मानक जावा या अमरूद का उपयोग कर पूरा किया जा सकता। समाधान मूल रूप से वही हैं और केवल वरीयता तक जो आप उपयोग करना चाहते हैं।

import com.google.common.base.Joiner; 
import com.google.common.collect.ImmutableList; 

import org.junit.Test; 

import java.util.List; 

import static org.junit.Assert.assertEquals; 

public class JoinListTest { 

    @Test 
    public void test_join() { 
     // create cases (don't need to use ImmutableList builder from guava) 
     final List<String> case1 = new ImmutableList.Builder<String>().add("A").build(); 
     final List<String> case2 = new ImmutableList.Builder<String>().add("A", "B").build(); 
     final List<String> case3 = new ImmutableList.Builder<String>().add("A", "B", "C").build(); 
     // test with standard java 
     assertEquals("A", joinListGrammaticallyWithJava(case1)); 
     assertEquals("A and B", joinListGrammaticallyWithJava(case2)); 
     assertEquals("A, B, and C", joinListGrammaticallyWithJava(case3)); 
     // test with guava 
     assertEquals("A", joinListGrammaticallyWithGuava(case1)); 
     assertEquals("A and B", joinListGrammaticallyWithGuava(case2)); 
     assertEquals("A, B, and C", joinListGrammaticallyWithGuava(case3)); 
    } 

    private String joinListGrammaticallyWithJava(final List<String> list) { 
     return list.size() > 1 
       ? String.join(", ", list.subList(0, list.size() - 1)) 
        .concat(String.format("%s and ", list.size() > 2 ? "," : "")) 
        .concat(list.get(list.size() - 1)) 
       : list.get(0); 
    } 

    private String joinListGrammaticallyWithGuava(final List<String> list) { 
     return list.size() > 1 
       ? Joiner.on(", ").join(list.subList(0, list.size() - 1)) 
        .concat(String.format("%s and ", list.size() > 2 ? "," : "")) 
        .concat(list.get(list.size() - 1)) 
       : list.get(0); 
    } 

} 
संबंधित मुद्दे