簡體   English   中英

檢查 arrayList 是否包含數組

[英]Check if an arrayList contains an array

我有一個包含 arrays 的 arrayList。 如何檢查 arrayList 是否包含指定的數組? 我使用.contains方法,它返回false而不是預期的true

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

public class main {
    public static void main(String[] args) {
        ArrayList<String[]> action = new ArrayList<String[]>();
        action.add(new String[]{"appple", "ball"});
        String[] items = new String[]{"appple", "ball"};
        if (action.contains(new String[]{"appple", "ball"})) {
            System.out.println("Yes");
        }
        System.out.println(action.contains(items)); // False
    }
}

當您創建不同的 arrays (即使內容相同)時,包含將導致錯誤。

但是,如果您這樣做:

 List<String[]> action = new ArrayList<String[]>();
 String[] items = new String[]{"apple","ball"};   
 action.add(items);
 if (action.contains(items)) 
     System.out.println("Yes");

這將打印Yes 此外,一些行為示例:

 String[] items = new String[]{"apple","ball"};   
 action.add(items);
 String[] clone = items.clone();
 String[] mirror = items;

 action.contains(clone); // false 
 action.contains(mirror); // true

 items[0]="horse";
 System.out.println(mirror[0]);        // "horse"
 System.out.println(clone[0]);         // "apple"
 System.out.println(action.get(0)[0]); // "horse"

 mirror[1]="crazy";
 System.out.println(clone[1]);         // "ball"
 System.out.println(action.get(0)[1]); // "crazy"
 System.out.println(items[1]);         // "crazy"

 clone[1]="yolo";
 System.out.println(action.get(0)[1]); // "crazy"
 System.out.println(items[1]);         // "crazy"
 System.out.println(mirror[1]);        // "crazy"

 System.out.println(action.get(0).hashCode());    //2018699554
 System.out.println(items.hashCode());            //2018699554
 System.out.println(clone.hashCode());            //1311053135
 System.out.println(mirror.hashCode());           //2018699554

自定義“ contains

這里的問題是,如果您想在之后搜索特定數組,您將丟失引用並且無法搜索項目,甚至無法復制具有相同精確值的數組。

作為一種解決方法,您可以實現自己的contains方法。 就像是:

如果您想獲取索引:

static int indexOfArray(List<String[]> list, String[] twin)
{        
   for (int i=0;i<list.size();i++)
      if (Arrays.equals(list.get(i),twin))
           return i;
   return -1;
}

然后,將其稱為:

String[] toSearch = new String[]{"apple","ball"};
int index = indexOfArray(action, toSearch); 

if (index>0) 
    System.out.println("Array found at index "+index);
else
    System.out.println("Array not found");

如果索引大於-1,您可以通過以下方式獲取原始數組:

String[] myArray = action.get(index);

HashMap + 標識符

另一種方法是通過為每個數組聲明一個標識符,將 arrays 存儲到HashMap中。 例如:

Base64 ID

這將對相同的值給出相同的結果,因為編碼值基於條目,而不是對象的引用。

 static String getIdentifier(String[] array)
 {
    String all="";
    for (String s : array)
        all+=s;
    return Base64.getEncoder().encodeToString(all.getBytes());
 }

然后你可以:

Map<String, String[]> arrayMap= new HashMap<>();
String[] items = new String[]{"apple","pear", "banana"}; // *[1234] 
action.add(items);
arrayMap.put(getIdentifier(items), items); // id = QUJDYWFh
//....
//Directly finding the twin will fail
String[] toSearch = new String[]{"apple","pear", "banana"}; // *[1556]
System.out.println(action.contains(toSearch)); // false

//But if we get the identifier based on the values
String arrId = getIdentifier(toSearch); // id = QUJDYWFh
System.out.println(action.contains(arrayMap.get(arrId)));  //true

//arrayMap.get(arrId)->  *[1234]
//.....

名稱

選擇一個代表名稱並將其用作 Id

Map<String, String[]> arrayMap= new HashMap<>();
String[] items = new String[]{"apple","pear", "banana"};
action.add(items);
arrayMap.put("fruits", items);
//...
System.out.println(action.contains(arrayMap.get("fruits"))); // true  
    

'contains' 方法比較等效的 hashCode 值。

所以如果你像下面這樣*,它就會通過。

public class main {
    public static void main(String[] args) {
        ArrayList<String[]> action = new ArrayList<String[]>();

        String[] items = new String[]{"appple","ball"};
        action.add(items);

        System.out.println("TO STRING");
        System.out.println("--"+action.get(0));
        System.out.println("--"+new String[]{"apple","ball"});

        System.out.println("HASHCODES");
        String[] sameValues = new String[]{"apple","ball"};
        System.out.println("--"+action.get(0).hashCode());    
        System.out.println("--"+items.hashCode());           
        System.out.println("--"+sameValues.hashCode());    
       
        System.out.println("CONTAINS");
        System.out.println("--"+action.contains(items));  // *this
        System.out.println("--"+action.contains(sameValues));
        System.out.println("--"+action.contains(new String[]{"apple","ball"}));
 
    }
}

結果是:

TO STRING
--[Ljava.lang.String;@7b1d7fff
--[Ljava.lang.String;@299a06ac
HASHCODES
--1243554231
--1243554231
--2548778887
CONTAINS
--true
--false
--false

關於打印數組時顯示的代碼,這些代碼不會覆蓋toString() ,因此您會得到:

getClass().getName() + '@' + Integer.toHexString(hashCode())

例如:

[Ljava.lang.String;@7b1d7fff

  • [代表一維數組
  • Ljava.lang.String代表類型
  • @
  • 7b1d7fff哈希碼的十六進制表示

但是,如果要比較這些值,可以使用以下方法。

public class main {
    public static void main(String[] args) {

        String[] items = new String[]{"apple","ball"};

        ArrayList<String> action = new ArrayList<>(Arrays.asList(items));

        if (action.contains("apple")) {
            System.out.println("Yes");
        }
    }
}

您可以遍歷此列表,並為每個元素(即數組)調用Arrays.equals方法來檢查 arrays 的相等性,直到第一次匹配,或者直到列表末尾沒有匹配。 在這種情況下,它可以為每個元素返回true

List<String[]> list = List.of(
        new String[]{"appple", "ball"},
        new String[]{"appple", "ball"});

String[] act = new String[]{"appple", "ball"};

System.out.println(list.stream()
        .anyMatch(arr -> Arrays.equals(arr, act))); // true

該方法在內部為數組的每個元素(即String )調用String#equals方法,因此此代碼也返回true

List<String[]> list = List.of(
        new String[]{new String("appple"), new String("ball")},
        new String[]{new String("appple"), new String("ball")});

String[] act = new String[]{new String("appple"), new String("ball")};

System.out.println(list.stream()
        .anyMatch(arr -> Arrays.equals(arr, act))); // true

根據 JavaDocs,“contains”方法使用“equals”和“hashCode”方法來檢查是否包含 object。

一個主要問題:你知道 arrays 的“等於”的實現是什么嗎?

檢查它,您可能會了解代碼的執行結果(提示:==)。

正如“Hovercraft Full Of Eels”所說,一個更好的設計將使用一些你理解/控制的 Collection 的列表,它是“equals”和“hashCode”方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM