2013-04-09 28 views
0

我正在尋找一種有效的方式來獲取從多個字符串中提取的字符串標記列表(例如,使用空白分隔符)。從Java中的多個字符串構建一個令牌列表的有效方法

例子:

String s1 = "My mom cook everyday"; 
String s2 = "I eat everyday"; 
String s3 = "Am I fat?"; 
LinkedList<String> tokens = new LinkedList<String>(); 
//any code to efficiently get the tokens 

//final result is tokens make of a list of the following tokens: 
//"My", "mom", "cook", "everyday", "I", "eat", "everyday", "Am", "I", "fat?". 

現在

  1. 我不知道那LinkedList是最有效的集合類使用(阿帕奇百科全書,番石榴,可他們幫忙嗎?)!
  2. 我打算使用Apache Commons的StringUtils,但split方法返回一個數組!所以,我應該從split返回的String對象數組中抽取一個for循環。是否高效:我不知道,split創建一個數組!
  3. 我從Guava讀了約Splitter,但this post指出StringUtils在實踐中更好。
  4. 怎麼樣ScannerJava.util。它似乎沒有分配任何額外的數據結構。不是嗎?

請畫出最高效的Java解決方案,甚至可以通過使用附加的廣泛使用的圖書館,像番石榴Apache的百科全書

+1

關於#3 - 你引述美國相反的帖子:*最後,我想我還是會用分離器的大部分時間。在小列表中,性能的差異可以忽略不計,Splitter感覺使用起來更好。不過我對結果感到驚訝,如果你正在分裂大量絃樂和性能是一個問題,它可能是值得考慮切換回下議院StringUtils的。* Plus中,Splitter是多少,** **遠不止強大的字符串#split或Apache Commons解決方案。 – Xaerxess 2013-04-09 14:57:00

+1

爲什麼對優化有如此多的興趣? – 2013-04-09 14:59:19

+0

@PaulVargas因爲我有數千個字符串需要從大文本中進行標記。 – 2013-04-09 15:01:30

回答

4

如果你有小弦和性能是不是一個問題,你可以只用addAll結合split這樣的:

String s1 = "My mom cook everyday"; 
String s2 = "I eat everyday"; 
String s3 = "Am I fat?"; 
List<String> tokens = new ArrayList<String>(); 

tokens.addAll(Arrays.asList(s1.split("\\s+"))); 
tokens.addAll(Arrays.asList(s2.split("\\s+"))); 
tokens.addAll(Arrays.asList(s3.split("\\s+"))); 

System.out.println(tokens); 

但是如果性能一個問題,這裏是一個替代的解決方案:

由於沒有定義如何獲得這些長文本,我假設他們進來InputStream。看看這種方法是不夠performatic滿足您的需求:

public List<String> readTokens(InputStream is) throws IOException{ 
    Reader reader = new InputStreamReader(is); 
    List<String> tokens = new ArrayList<String>(); 
    BufferedReader bufferedReader = new BufferedReader(reader); 
    String line = null; 
    while((line = bufferedReader.readLine()) != null){ 
     String[] lineTokens = StringUtils.split(line, " "); 
     for(int i = 0 ; i < lineTokens.length ; i++){ 
      tokens.add(lineTokens[i]); 
     } 
    } 
    return tokens; 
} 

併爲您在年底將關於ArrayList VS LinkedList聲明,也許你應該閱讀this

+0

我讀到從字符串拆分不是一個真正有效的解決方案。這就是爲什麼,例如,Apache Commons自帶'StringUtils.split'!也許是因爲它使用模式... – 2013-04-09 14:53:07

+0

你的字符串真的很大嗎?因爲在不是問題的情況下不應該擔心 – 2013-04-09 14:56:04

+1

此外,當要插入的元素的數量很高時,ArrayList不像LinkedList那樣高效!實際上,ArrayList只是一個數組的「包裝器」,它帶有一個默認大小的數組,並且一旦您超過默認大小,您必須創建一個新數組並將舊值複製到較新的數組中!非常無效! – 2013-04-09 14:57:44

0

或只是Arrays.asList((s1 + " " + s2 + " " + s3).split("\\s+"))

0

首先使用分隔符連接字符串(請參閱Join a string using delimiters)。然後:

LinkedList<String> tokens = new LinkedList<String>(); 
StringTokenizer st = new StringTokenizer(yourstr); // " " as a default delimiter 
while (st.hasMoreTokens()) { 
    tokens.add(st.nextToken()); 
} 

您是否正在尋找高效或高性能的解決方案(即您的約束/參考性能)?

5
for (String str : Arrays.asList(s1, s2, s3)) { 
    Iterables.addAll(tokens, Splitter.on(' ').split(str)); 
} 

將是我會這樣做的方式。也就是說,對於幾乎所有的用例,ArrayList優於LinkedList;沒有進一步的數據,我們真的不知道你是否在LinkedList是最好的罕見情況之一。

+0

我正在做一些測試... – 2013-04-09 15:32:22

0
 import java.util.ArrayList; 
    import java.util.Collections; 


    public class stringintotoken { 
String s="my name is tarun bharti"; 
ArrayList <String> words=new ArrayList<String>(); 
public static void main(String[] args) 
{ 
    stringintotoken st=new stringintotoken(); 
    st.go(); 
} 
public void go() 
{ 
    wordlist(); 
    System.out.println(words); 
    Collections.sort(words); 
    System.out.println(words); 

} 
public void wordlist() 
{ 
    String[] tokens=s.split(" "); 
    for(int i=0;i<tokens.length;i++) 
    { 
    words.add(tokens[i]); 
    } 
} 

}

相關問題