2012-09-25 108 views
1

美好的一天。Longs列表如何檢查它是否包含值?

我試圖檢查一個long的列表是否不包含某個值。這似乎好像是條件,從來沒有遇到過,儘管我知道,未必是一個值在一定鏈表存在...

for(int i : organizationIDs){ 
    if(!ListOfOrgIds.contains(Long.valueOf(i))){ 
     addThese.add(new Long(i)); 
    } 
} 

我基本上是尋找一種不會在ORGID的存在價值數組,如果它不存在,將其添加到addThese鏈接列表中...我是否錯過了Long應該知道的一些細微差別?

ListOfOrgIds在調試器中

14057 
821 
18021 

OrganizationIDs發現在調試器中

821 
14057 
18021 

讓我這樣說吧發現,我要找就在調試器,它告訴我, ListOfOrgIds.contains(i) 是錯誤的...這是明顯不真實的... enter image description here

具體而言,看ListOfOrgs的價值觀......

enter image description here

821確實是在那裏。爲什麼我在包含呼叫中收到錯誤消息?

+0

你能告訴更多的代碼。由於這部分代碼似乎是正確的。除非有一個與'addThese.add(沒問題)'或'的是ListOfOrgIds'我們不知道他們是怎麼看.. –

+0

順便說一句,爲什麼你創建了一個'長'列表',即使你正在給它們加'整數'值? –

+0

似乎沒有任何一個 –

回答

2

您遇到的問題是,Java不允許被擴大後再裝箱原始,只有盒裝然後加寬。這意味着一個int不能變成一個Long,但是一個int可以變成一個Object(通過Integer)。 this question的最佳答案很好地描述了它。在這種情況下,您不會收到任何編譯反饋,因爲contains方法不使用list的類型參數,它接受任何對象。這也讓我在過去多次遇到過。

以下是SSCCE顯示您所得到的結果和一個工作示例。注意所有需要的是明確地將int轉換爲long。

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

public class BoxingTest { 

    public static void main(String[] args) throws Exception { 

     List<Integer> intList = Arrays.asList(new Integer[]{14, 24, 69}); 
     List<Long> sourceLongList = Arrays.asList(new Long[]{14L, 17L}); 

     List<Long> resultsList; 
     /* Test as in question code */ 
     resultsList = new ArrayList<Long>(); 
     for(int i : intList){ 
      if(!sourceLongList.contains(i)){ 
       resultsList.add(new Long(i)); 
      } 
     } 
     printList(resultsList); 

     /* Can't box then widen, so cast */ 
     resultsList = new ArrayList<Long>(); 
     for(int i : intList){ 
      if(!sourceLongList.contains((long)i)){ 
       resultsList.add(new Long(i)); 
      } 
     } 
     printList(resultsList); 

    } 

    private static <T> void printList(List<T> values){ 
     StringBuilder contents = new StringBuilder(); 
     for(T value : values){ 
      contents.append(value); 
      contents.append(" "); 
     } 
     System.out.println("List contains: " + contents); 
    } 

} 
1

我想說的第一點是,看起來使用Set會更好,因爲它不允許有重複的元素。換句話說,這樣做的:

Set<Long> ids = new HashSet<Long>(); 
ids.add(Long.valueOf(1)); 
ids.add(Long.valueOf(1)); 
System.out.println(ids.size()); 

將打印1,不2像它會爲List

我不確定你在找什麼確切的操作,但有三種可能的選擇:聯合,交叉和相對補償。有關其正式定義和維恩圖,請參見this Wikipedia section on the Set page

聯盟

結果:AB所有元素將在C

要執行此操作:

Set<Long> a = ... ; 
Set<Long> b = ... ; 
Set<Long> c = new HashSet<Long>(a); 
c.addAll(b); 

交叉口

結果:僅在兩個AB元件將在C

要執行此操作:

Set<Long> a = ... ; 
Set<Long> b = ... ; 
Set<Long> c = new HashSet<Long>(a); 
c.retainAll(b); 

相對補

結果:C將包含不同之處在於在B

雞舍A所有元素要執行此操作:

Set<Long> a = ... ; 
Set<Long> b = ... ; 
Set<Long> c = new HashSet<Long>(a); 
c.removeAll(b); 

此外,轉換一個ListSet

List<Long> idsAsList = ... ; 
Set<Long> idsAsSet = new HashSet<Long>(idsAsList); 

在磁盤陣列轉換爲Set,你必須做不同的事情取決於如果您有一個long[]Long[]上(注意瓶蓋)。對於long[],你必須手動複製:如果是Long[]

long[] idsAsArray = ... ; 
Set<Long> idsAsSet = new HashSet<Long>(); 
for (long l : idsAsArray) { 
    idsAsSet.add(Long.valueOf(l)); 
} 

,您可以使用Arrays.asList

Long[] idsAsArray = ... ; 
Set<Long> ids = new HashSet<Long>(Arrays.asList(idsAsArray)); 
+0

不是真的要關心騙局。無論如何,究竟究竟是什麼?一些哈希表?我不小心複製了相同的變量輸出。這將反映在我更新我的帖子時。 – SoftwareSavant

+0

一組是另一種不允許重複的集合類型。把它想象成一個列表,但沒有排序(這可能與你的情況不相關),也沒有重複元素的可能性(在你的情況下可能不需要)。在這種情況下,它也快得多,因爲對於任何'List','removeAll'和'retainAll'都是_O(n)= n^2_,但是'HashSet'是_O(n)= n_。在幕後,它使用一種哈希表來實現,但它本身不是哈希表,因爲它不像哈希表那樣「映射」。 – Brian

+0

另外,你是否降低了我的答案?只有當解決方案在技術上不正確或不回答問題時才應使用降級提示。請參閱[這個問題]的答案(http://meta.stackexchange.com/questions/2451/why-do-you-cast-downvotes-on-answers)以獲取有關經驗豐富的SO成員如何感受downvotes的信息(並且應該不)被使用。 – Brian

相關問題