2009-09-25 11 views
36

मैं एक सीएसवी फ़ाइल को सूचियों (स्ट्रिंग्स) की सूची में पढ़ने की कोशिश कर रहा हूं, डेटाबेस से कुछ डेटा प्राप्त करने के लिए इसे पास करता हूं, नए डेटा की सूचियों की एक नई सूची बनाता हूं , फिर सूचियों की सूची को पास करें ताकि इसे एक नई सीएसवी फ़ाइल में लिखा जा सके। मैंने पूरी तरह से देखा है, और मुझे यह उदाहरण नहीं मिल रहा है कि इसे कैसे करेंजावा में लिस्ट की सूची के साथ काम करना

मैं सरल सरणी का उपयोग नहीं करता क्योंकि फाइलें आकार में भिन्न होंगी और मुझे नहीं पता कि सरणी के आयामों के लिए क्या उपयोग करना है। मुझे फाइलों से निपटने में कोई समस्या नहीं है। मुझे यकीन नहीं है कि सूचियों की सूची से कैसे निपटें।

मुझे मिले अधिकांश उदाहरण बहु-आयामी सरणी बनाएंगे या लूप के अंदर क्रियाएं करेंगे जो फ़ाइल से डेटा पढ़ रहे हैं। मुझे पता है कि मैं ऐसा कर सकता हूं, लेकिन मैं ऑब्जेक्ट उन्मुख कोड लिखना चाहता हूं। यदि आप कुछ उदाहरण कोड प्रदान कर सकते हैं या मुझे संदर्भ में इंगित कर सकते हैं, तो यह बहुत अच्छा होगा।

उत्तर

105
ArrayList<ArrayList<String>> listOLists = new ArrayList<ArrayList<String>>(); 
ArrayList<String> singleList = new ArrayList<String>(); 
singleList.add("hello"); 
singleList.add("world"); 
listOLists.add(singleList); 

ArrayList<String> anotherList = new ArrayList<String>(); 
anotherList.add("this is another list"); 
listOLists.add(anotherList); 
9

यहाँ एक उदाहरण है कि सूचियों की एक सूची में सीएसवी स्ट्रिंग की एक सूची पढ़ता है और उसके बाद सूचियों की उस सूची के माध्यम से लूप और CSV तार वापस प्रिंट कंसोल के लिए बाहर है।

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

public class ListExample 
{ 
    public static void main(final String[] args) 
    { 
     //sample CSV strings...pretend they came from a file 
     String[] csvStrings = new String[] { 
       "abc,def,ghi,jkl,mno", 
       "pqr,stu,vwx,yz", 
       "123,345,678,90" 
     }; 

     List<List<String>> csvList = new ArrayList<List<String>>(); 

     //pretend you're looping through lines in a file here 
     for(String line : csvStrings) 
     { 
      String[] linePieces = line.split(","); 
      List<String> csvPieces = new ArrayList<String>(linePieces.length); 
      for(String piece : linePieces) 
      { 
       csvPieces.add(piece); 
      } 
      csvList.add(csvPieces); 
     } 

     //write the CSV back out to the console 
     for(List<String> csv : csvList) 
     { 
      //dumb logic to place the commas correctly 
      if(!csv.isEmpty()) 
      { 
       System.out.print(csv.get(0)); 
       for(int i=1; i < csv.size(); i++) 
       { 
        System.out.print("," + csv.get(i)); 
       } 
      } 
      System.out.print("\n"); 
     } 
    } 
} 

मुझे लगता है कि बहुत सरल है। बस कुछ अंक नोटिस:

  1. मैं "सूची" "ArrayList" के बजाय बाईं ओर का उपयोग करना चाहिये जब सूची वस्तुओं का निर्माण। अंतरफलक "सूची" के चारों ओर पारित करना बेहतर है क्योंकि तब बाद में आपको वेक्टर जैसे कुछ का उपयोग करने की आवश्यकता है (उदा। अब आपको सिंक्रनाइज़ सूचियों की आवश्यकता है), आपको केवल "नया" कथन के साथ लाइन को बदलने की आवश्यकता है। कोई फर्क नहीं पड़ता कि आप किस सूची का उपयोग करते हैं, उदाहरण के लिए। वेक्टर या ऐरेलिस्ट, आप अभी भी लगभग List<String> पास करते हैं।

  2. ऐरेलिस्ट कन्स्ट्रक्टर में, आप सूची को खाली छोड़ सकते हैं और यह एक निश्चित आकार के लिए डिफ़ॉल्ट हो जाएगा और फिर आवश्यकतानुसार गतिशील रूप से बढ़ेगा। लेकिन यदि आप जानते हैं कि आपकी सूची कितनी बड़ी हो सकती है, तो आप कभी-कभी कुछ प्रदर्शन सहेज सकते हैं। उदाहरण के लिए, यदि आप पता था कि वहाँ हमेशा आपकी फ़ाइल में 500 लाइनों होने के लिए, तो तुम कर सकते हो जा रहे थे:

List<List<String>> csvList = new ArrayList<List<String>>(500);

इस तरह आप प्रसंस्करण समय बर्बाद कभी नहीं होगा अपनी सूची गतिशील रूप से विकसित करने के लिए इंतजार कर बढ़ता है। यही कारण है कि मैं कन्स्ट्रक्टर को "linePieces.length" पास करता हूं। आमतौर पर एक बड़ा सौदा नहीं है, लेकिन कभी-कभी सहायक होता है।

आशा है कि मदद करता है!

+2

आपका उदाहरण, बल्कि विस्तृत करते हुए, है बल्कि भ्रामक भी। आसपास के उद्धरणों के लिए कोई सम्मान नहीं होने के साथ अल्पविराम में लाइन और विभाजन लाइनों द्वारा सीएसवी फ़ाइल लाइन पढ़ना परेशानी के लिए पूछ रहा है। – ChssPly76

+2

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

5

@tster द्वारा प्रदान किया गया उदाहरण दिखाता है कि सूची की सूची कैसे बनाएं। मैं ऐसी सूची में पुनरावृत्ति के लिए एक उदाहरण प्रदान करूंगा।

Iterator<List<String>> iter = listOlist.iterator(); 
while(iter.hasNext()){ 
    Iterator<String> siter = iter.next().iterator(); 
    while(siter.hasNext()){ 
     String s = siter.next(); 
     System.out.println(s); 
    } 
} 
14

यदि आप वास्तव में जानना चाहते हैं कि जावा में पूरी तरह से सीएसवी फाइलों को संभालते हैं, तो अपने आप से सीएसवी रीडर/लेखक को लागू करने का प्रयास करना अच्छा नहीं है। नीचे देखें।

http://opencsv.sourceforge.net/

अपनी CSV दस्तावेज़ डबल उद्धरण या नई-पंक्तियों में शामिल है, तो आप कठिनाइयों का सामना करना होगा।

ऑब्जेक्ट उन्मुख दृष्टिकोण को पहले सीखने के लिए, अन्य कार्यान्वयन (जावा द्वारा) को देखने में आपकी मदद मिलेगी। और मुझे लगता है कि सूची में एक पंक्ति का प्रबंधन करने का यह अच्छा तरीका नहीं है।सीएसवी आपको अंतर कॉलम आकार रखने की अनुमति नहीं देता है।

+17

+1। हालांकि, यह ** सीएसवी रीडर/लेखक को विशेष रूप से एक जावा नौसिखिया के लिए लागू करने के लिए * कोशिश * अच्छा है - आप रास्ते में बहुत सारी चीजें सीखते हैं। – ChssPly76

2

मैं दूसरा क्या करूंगा xrath ने कहा - आप सीएसवी पढ़ने/लिखने को संभालने के लिए मौजूदा पुस्तकालय का उपयोग करना बेहतर कर रहे हैं।

आप अपने खुद के ढांचे रोलिंग पर योजना है, तो मैं भी अपने कार्यान्वयन के रूप में List<List<String>> का उपयोग कर चाहते हैं का सुझाव देते हैं न - आप शायद बेहतर CSVDocument और CSVRow वर्गों को लागू होगी (जो आंतरिक रूप से क्रमश: एक List<CSVRow> या List<String> का उपयोग करता है हो सकता है), हालांकि उपयोगकर्ताओं के लिए, केवल एक अपरिवर्तनीय सूची या एक सरणी का पर्दाफाश करें।

बस List<List<String>> का उपयोग करके बहुत से अनचेक किनारे के मामले छोड़ते हैं और कार्यान्वयन विवरणों पर भरोसा करते हैं - जैसे, डेटा से डेटा को अलग से संग्रहीत किया जाता है? या वे List<List<String>> की पहली पंक्ति में हैं? क्या होगा यदि मैं सूचकांक के बजाय पंक्ति से कॉलम हेडर द्वारा डेटा तक पहुंचना चाहता हूं?

क्या होता है जब आपको इन बातों की कॉल:

// reads CSV data, 5 rows, 5 columns 
List<List<String>> csvData = readCSVData(); 
csvData.get(1).add("extraDataAfterColumn"); 
// now row 1 has a value in (nonexistant) column 6 
csvData.get(2).remove(3); 
// values in columns 4 and 5 moved to columns 3 and 4, 
// attempting to access column 5 now throws an IndexOutOfBoundsException. 

आप यह सब जब CSV फ़ाइल लिखने को मान्य करने का प्रयास कर सकता है, और यह कुछ मामलों में काम कर सकते हैं ... लेकिन दूसरों में, आप करेंगे एक अपवाद के उपयोगकर्ता को सतर्क रहें जहां से गलत परिवर्तन किया गया था, जिसके परिणामस्वरूप मुश्किल डीबगिंग हुई थी।

3

कुछ इस तरह से पढ़ने के लिए काम करेगा:

String filename = "something.csv"; 
BufferedReader input = null; 
List<List<String>> csvData = new ArrayList<List<String>>(); 
try 
{ 
    input = new BufferedReader(new FileReader(filename)); 
    String line = null; 
    while ((line = input.readLine()) != null) 
    { 
     String[] data = line.split(","); 
     csvData.add(Arrays.toList(data)); 
    } 
} 
catch (Exception ex) 
{ 
     ex.printStackTrace(); 
} 
finally 
{ 
    if(input != null) 
    { 
     input.close(); 
    } 
} 
0

इसके अलावा यह कैसे पाश के लिए उन्नत का उपयोग कर सूची की सूची मुद्रित करने के लिए का एक उदाहरण है:

public static void main(String[] args){ 
     int[] a={1,3, 7, 8, 3, 9, 2, 4, 10}; 
     List<List<Integer>> triplets; 
     triplets=sumOfThreeNaive(a, 13); 
     for (List<Integer> list : triplets){ 
      for (int triplet: list){ 
       System.out.print(triplet+" "); 
      } 
      System.out.println(); 
     } 
    } 
संबंधित मुद्दे