Java,简化检查int数组是否包含int


94

基本上,我的同伴一直在说,我可以使用另一种检查int数组是否包含int的方式来缩短代码,尽管他不会告诉我它是什么:P。

当前:

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}

也尝试过此方法,尽管由于某种原因它总是返回false。

public boolean contains(final int[] array, final int key) {
    return Arrays.asList(array).contains(key);
}

有人可以帮我吗?

谢谢。


8
您的Arrays.asList(...)调用使用一个变量,即它将将您可能传递给该参数的任意数量的参数包装在List中。就您而言,您将获得具有单个元素的数组列表,并且该列表显然不包含int。
sarcan

您的评论意味着什么?
sarcan

检查Hashset基于重试机制的答案。这是最快的方法。
阿米特·德什潘德

我看不出要缩短原始代码的意义,因为您的参数是一个原始数组,并且您的代码非常清晰明了。ArrayList实现也是如此。
Genzer

我不会缩短您的代码。(1)arraylist做与您相同的事情。(2)-更重要的是,使用Arrays.asList的短代码创建了新对象,这在某些性能关键代码中可能会出现问题。第一个代码段是您可以做的最好的事情。
马丁·波德瓦

Answers:


38

这是Java 8解决方案

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}

63

您可以简单地使用ArrayUtils.containsfrom Apache Commons Lang library

public boolean contains(final int[] array, final int key) {     
    return ArrayUtils.contains(array, key);
}

1
只要您使用ArrayUtils,是否有任何理由不使用ArrayUtils.contains
mjohnsonengr 2014年

2
毫无理由:)
Reimeus 2014年

20
值得注意的是它ArrayUtils.contains()Apache Commons Lang库的一部分。即使那是一个很棒的库,添加外部依赖关系只是为了检查数组是否包含元素可能仍然不是一个好主意:D
Krzysiek

1
ArrayUtils已经成为过去。Java 8+和Guava都具有惊人的优点!!
TriCore

34

这是因为Arrays.asList(array)return List<int[]>array参数被视为要包装的一个值(您将获得整数数组的列表),而不是vararg。

请注意,它确实适用于对象类型(不是基元):

public boolean contains(final String[] array, final String key) {
    return Arrays.asList(array).contains(key);
}

甚至:

public <T>  boolean contains(final T[] array, final T key) {
    return Arrays.asList(array).contains(key);
}

但是您不能拥有,List<int>并且自动装箱在这里不起作用。


1
为什么自动装箱不起作用,是因为它被声明为最终装箱?
subhashis

19

Guava为原始类型提供了其他方法。其中有一个contains方法,该方法采用与您相同的参数。

public boolean contains(final int[] array, final int key) {
    return Ints.contains(array, key);
}

您也可以静态导入番石榴版本。

参见解释番石榴基元


18

另一种方式:

public boolean contains(final int[] array, final int key) {  
     Arrays.sort(array);  
     return Arrays.binarySearch(array, key) >= 0;  
}  

这将修改传入的数组。您可以选择复制数组并在原始数组上工作,即,int[] sorted = array.clone();
但这只是短代码的示例。运行时是O(NlogN)您的方式O(N)


30
我想如果contains方法修改了我的数组我会感到惊讶。
Zong

@ZongLi:这只是OP的一个示例。如果我们挑剔的话,请更新OP
Cratylus

5
来自binarySearch()的javadoc:“当且仅当找到键时,返回值才> =0。” 所以应该返回Arrays.binarySearch(array,key)> = 0!
icza 2014年

补充:如果不包含可能不是-1的值的键,则binarySearch()的返回值为(-(插入点)-1)。
icza

这不可能是-1如果它正试图将是真实的。“插入点定义为将关键字插入列表的点:第一个元素的索引大于关键字,如果列表中的所有元素均小于指定的关键字,则为list.size()。 ”。需要说>= 0
布莱恩(Brian)


1

1.一次性使用

List<T> list=Arrays.asList(...)
list.contains(...)

2.如果您多次使用HashSet,则应考虑性能。

Set <T>set =new HashSet<T>(Arrays.asList(...));
set.contains(...)

1

试试这个:

public static void arrayContains(){
    int myArray[]={2,2,5,4,8};

    int length=myArray.length;

    int toFind = 5;
    boolean found = false;

    for(int i = 0; i < length; i++) {
        if(myArray[i]==toFind) {
            found=true;
        }
    }

    System.out.println(myArray.length);
    System.out.println(found); 
}

1

您可以使用以下Java 8代码将原始int数组转换为Integer的数组列表,

List<Integer> arrayElementsList = Arrays.stream(yourArray).boxed().collect(Collectors.toList());

然后使用contains()方法检查列表中是否包含特定元素,

boolean containsElement = arrayElementsList.contains(key);

0

这在Java 8中工作

public static boolean contains(final int[] array, final int key)
{
return Arrays.stream(array).anyMatch(n->n==key);
}

它应该在第一次匹配时立即返回,相反,即使它确实找到了匹配项,它仍然会扫描数组中的所有项目。(考虑一系列Trilion物品)
TriCore

您是对的,尝试使用此公共静态布尔包含(final int [] array,final int key){return Arrays.stream(array).anyMatch(n-> n == key); }
Farhad Baghirov's

Java 8流anyMatch是一种短路操作,不会扫描阵列中的所有项目。
LordParsley '18

@LordParsley上面代码的目标是检查数组中的元素,而不是扫描数组中的所有元素。
Farhad Baghirov

抱歉,我看到答案已被编辑。我只是重申这是正确的,因为如果发现其中一部分,则无需扫描所有内容。
LordParsley18年

0

您可以使用java.util.Arrays类数组转换T[?]List<T>用类似的方法对象contains

Arrays.asList(int[] array).contains(int key);

-1

根据您要使用的int数组的大小,如果使用集合.contains而不是一次遍历一个元素遍历数组,您将获得更好的性能:

import static org.junit.Assert.assertTrue;
import java.util.HashSet;

import org.junit.Before;
import org.junit.Test;

public class IntLookupTest {

int numberOfInts = 500000;
int toFind = 200000;
int[] array;

HashSet<Integer> intSet;

@Before
public void initializeArrayAndSet() {
    array = new int[numberOfInts];
    intSet = new HashSet<Integer>();
    for(int i = 0; i < numberOfInts; i++) {
        array[i] = i;
        intSet.add(i);
    }
}

@Test
public void lookupUsingCollections() {
    assertTrue(intSet.contains(toFind));
}

@Test
public void iterateArray() {
    assertTrue(contains(array, toFind));

}

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}
}

-1

解决方案1

由于最初的问题只需要一种简化的解决方案(而不是更快的解决方案),因此这里是一线解决方案:

public boolean contains(int[] array, int key) {
    return Arrays.toString(array).matches(".*[\\[ ]" + key + "[\\],].*");
}

说明:Arrays.toString()状态的Javadoc 结果用方括号括起来,相邻的元素用字符“,”(逗号后跟空格)分隔。因此,我们可以指望这一点。首先,我们转换array为字符串,然后检查key此字符串中是否包含。当然,我们不能接受“子数字”(例如,“ 1234”包含“ 23”),因此我们必须寻找这样的模式,在模式key前加一个中括号或一个空格,后跟一个中括号或逗号。

注意:使用的正则表达式模式也可以正确处理负数(其字符串表示形式以减号开头)。

解决方案#2

该解决方案已经发布,但是包含错误,因此我发布了正确的解决方案:

public boolean contains(int[] array, int key) {
    Arrays.sort(array);
    return Arrays.binarySearch(array, key) >= 0;
}

此解决方案也有一个副作用:它修改了array(排序)。


字符串handlig通常很昂贵,为什么有人应该将整数视为字符串?
Denys Vitali

@DenysVitali因为op已经有了一个行之有效的解决方案,所以他正在寻找更短的解决方案。而且这些较短。这个问题与性能无关。
icza

我应该有误解的问题的话,对不起,问
丹尼斯·维塔利

-5

尝试 Integer.parseInt()这样做.....

public boolean chkInt(final int[] array){
    int key = false;

    for (Integer i : array){


          try{

                   Integer.parseInt(i);
                   key = true;
                   return key;

             }catch(NumberFormatException ex){

                   key = false;

                   return key;

              }


     }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.