2

long のリストに特定の値が含まれていないかどうかを確認しようとしています。特定のリンクされたリストに1つの値が存在しないことを知っていても、その条件は決して満たされないように見えます...

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

基本的に、orgID の配列に存在しない値を探しています。存在しない場合は、addTheseリンクされたリストに追加します...知っておくべき Long のニュアンスが欠けていますか?

デバッガーで見つかった ListOfOrgIds

14057
821
18021

デバッガーで検出された OrganizationID

821
14057
18021

このように言えば、私はデバッガーを正しく見ていますが、それ ListOfOrgIds.contains(i) は間違っていると言っています...これは明らかに真実ではありません...ここに画像の説明を入力

具体的には、ListOfOrgs の値を見てください...

ここに画像の説明を入力

821は確かにあります。contains 呼び出しで false が返されるのはなぜですか?

4

2 に答える 2

2

あなたが抱えている問題は、Javaがプリミティブを拡大してからボックス化することを許可せず、ボックス化してから拡大することだけを許可しないことです。これは、int が Long になることはできませんが、int は (Integer を介して) Object になる可能性があることを意味します。この質問に対する一番上の回答は、それをかなりよく説明しています。この場合、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);
    }

}
于 2012-09-25T21:13:50.077 に答える
1

私が作りたい最初のポイントは、Set要素の重複を許可しないため、使用したほうがよいように思われるということです。つまり、次のことを行います。

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

の場合とは異なり12が出力されListます。

あなたが探している正確な操作はわかりませんが、必要な操作は 3 つあります。結合、交差、相対補数です。それらの正式な定義とベン図については、このウィキペディアのセット ページのセクションを参照してください

連合

結果: と のすべての要素が にAなりBますC

この操作を実行するには:

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

交差点

A結果:との両方の要素のみBが になりますC

この操作を実行するには:

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

相対補体

結果:にあったものを除くCすべての要素が含まれますAB

この操作を実行するには:

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

さらに、 a を aに変換するListにはSet:

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

配列を に変換するには、 があるか があるかSetによって、異なる処理を行う必要があります(大文字に注意してください)。の場合、手動でコピーする必要があります。long[]Long[]long[]

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

の場合はLong[]、次を使用できますArrays.asList

Long[] idsAsArray = ... ;
Set<Long> ids = new HashSet<Long>(Arrays.asList(idsAsArray));
于 2012-09-25T18:27:01.137 に答える