[英]Fastest way to lookup a String value
我有一個簡單的應用程序,可以從大型文本文件中讀取小字符串中的數據,並將其保存到數據庫中。 為了實際保存每個這樣的String,應用程序會多次(可能數千次或多次)調用以下方法:
setValue(String value)
{
if (!ignore(value))
{
// Save the value in the database
}
}
當前,我通過依次比較一組字符串來實現ignore()
方法,例如
public boolean ignore(String value)
{
if (value.equalsIgnoreCase("Value 1") || (value.equalsIgnoreCase("Value 2"))
{
return true;
}
return false;
}
但是,由於我需要檢查許多將在代碼另一部分定義的“可忽略的”值,因此我需要使用數據結構進行此檢查,而不是使用多個連續的if
語句。
因此,我的問題是,從標准Java到實現該目標的最快數據結構是什么? HashMap? 一套? 還有嗎
初始化時間不是問題,因為它將靜態發生,並且每次應用程序調用一次。
編輯:到目前為止,建議的解決方案(包括HashSet)似乎比僅使用String []包含所有被忽略的單詞並針對其中每個單詞運行“ equalsIgnoreCase”要慢。
使用HashSet (以小寫形式存儲值)及其contains()方法,該方法具有比TreeSet更好的查找性能(contains時間與log-time相比)。
Set<String> ignored = new HashSet<String>();
ignored.add("value 1"); // store in lowercase
ignored.add("value 2"); // store in lowercase
public boolean ignore(String value) {
return ignored.contains(value.toLowerCase());
}
以小寫形式存儲值並搜索小寫輸入避免了在比較期間處理大小寫的麻煩,因此您可以獲得HashSet實現的全速和要編寫的零收集相關代碼(例如Collator,Comparator等)。
已編輯
感謝Jon Skeet指出某些土耳其語字符在調用toLowerCase()
時表現toLowerCase()
,但是如果您不打算支持土耳其語輸入(或其他不帶標准大小寫問題的語言),那么這種方法將非常適合您。
在大多數情況下,我通常以HashSet<String>
開頭-但是,由於您不區分大小寫,因此這會變得有點困難。
您可以嘗試使用TreeSet<Object>
使用適當的Collator
來區分大小寫。 例如:
Collator collator = Collator.getInstance(Locale.US);
collator.setStrength(Collator.SECONDARY);
TreeSet<Object> set = new TreeSet<Object>(collator);
請注意,您不能創建TreeSet<String>
因為Collator
僅實現Comparator<Object>
。
編輯:雖然上述版本僅適用於字符串,但創建TreeSet<CollationKey>
可能更快:
Collator collator = Collator.getInstance(Locale.US);
collator.setStrength(Collator.SECONDARY);
TreeSet<CollationKey> set = new TreeSet<CollationKey>();
for (String value : valuesToIgnore) {
set.add(collator.getCollationKey(value));
}
然后:
public boolean ignore(String value)
{
return set.contains(collator.getCollationKey(value));
}
這將是不錯的存儲排序鍵的所有忽略值的方法,但建議盡量避免進行測試時,創造新的整理鍵,但我不知道這樣做的一種方式。
如果使用Java 7,這是一種快速的方法:
public boolean ignore(String value) {
switch(value.toLowerCase()) { // see comment Jon Skeet
case "lowercased_ignore_value1":
case "lowercased_ignore_value2":
// etc
return true;
default:
return false;
}
}
將要忽略的單詞添加到列表中,然后僅檢查單詞是否在該列表中。
這使其成為動態的。
似乎String [](在性能方面)比其他建議的方法稍好,所以我將使用它。
簡直是這樣的:
public boolean ignore(String value)
{
for (String ignore:IGNORED_VALUES)
{
if (ignore.equalsIgnoreCase(value))
{
return true;
}
return false;
}
IGNORED_VALUES對象只是一個String [],其中包含所有被忽略的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.