Java, Đơn giản hóa kiểm tra xem mảng int có chứa int không


94

Về cơ bản, người bạn đời của tôi đã nói rằng tôi có thể làm cho mã của mình ngắn hơn bằng cách sử dụng một cách khác để kiểm tra xem một mảng int có chứa int hay không, mặc dù anh ấy sẽ không cho tôi biết nó là gì: P.

Hiện hành:

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

Cũng đã thử điều này, mặc dù nó luôn trả về false vì một số lý do.

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

Bất cứ ai có thể giúp tôi ra ngoài?

Cảm ơn bạn.


8
Lệnh gọi Arrays.asList (...) của bạn có một vararg, nghĩa là nó sẽ bao bọc số lượng đối số tùy ý mà bạn có thể chuyển vào đó trong một Danh sách. Trong trường hợp của bạn, bạn đang nhận được danh sách các mảng với một phần tử duy nhất và danh sách này rõ ràng không chứa int.
châm biếm

Bình luận của bạn có ý nghĩa gì bây giờ?
châm biếm

kiểm tra Hashsetcâu trả lời dựa trên cơ chế tái thẩm. Đó là cách nhanh nhất.
Amit Deshpande

Tôi không thấy có điểm nào khi làm cho mã gốc của bạn ngắn hơn vì đối số của bạn là một mảng nguyên thủy và mã của bạn rất rõ ràng và thẳng thắn. ArrayListviệc triển khai cũng như vậy.
Genzer

Tôi sẽ không làm cho mã của bạn ngắn hơn. (1) danh sách mảng thực hiện điều tương tự như bạn đã làm. (2) - điều quan trọng hơn là mã rút ngắn sử dụng Arrays.asList tạo ra đối tượng mới, có thể là vấn đề trong một số mã quan trọng về hiệu suất. Đoạn mã đầu tiên là điều tốt nhất bạn có thể làm.
Martin Podval

Câu trả lời:


38

Đây là giải pháp Java 8

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

63

Bạn chỉ có thể sử dụng ArrayUtils.containstừ Apache Commons Lang library.

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

1
Chừng nào bạn đang sử dụng ArrayUtils, là có bất kỳ lý do để không sử dụng ArrayUtils.contains
mjohnsonengr

2
Không có lý do gì cả :)
Reimeus

20
Cần lưu ý rằng đó ArrayUtils.contains()là một phần của Apache Commons Langthư viện. Mặc dù đó là một lib lớn, nó có lẽ vẫn không phải là một ý tưởng tốt để thêm phụ thuộc bên ngoài chỉ để kiểm tra xem mảng chứa một phần tử: D
Krzysiek

1
ArrayUtils đã là dĩ vãng. Java 8+ và Guava có những tính năng khá tuyệt vời !!
TriCore

34

Đó là bởi vì sự Arrays.asList(array)trở lại List<int[]>.arrayđối số được coi là một giá trị bạn muốn bao bọc (bạn nhận được danh sách các mảng int), không phải là vararg.

Lưu ý rằng nó không làm việc với các loại đối tượng (không nguyên thủy):

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

hoặc thậm chí:

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

Nhưng bạn không thể có List<int>và tính năng autoboxing không hoạt động ở đây.


1
Tại sao autoboxing không hoạt động, có phải vì nó được khai báo là cuối cùng?
subhashis

19

Ổi cung cấp các phương pháp bổ sung cho các loại nguyên thủy. Trong số đó, một phương thức chứa lấy các đối số giống như phương thức của bạn.

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

Bạn cũng có thể nhập tĩnh phiên bản ổi.

Xem Giải thích về Nguyên thủy của Ổi


18

Một cách khác:

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

Điều này sửa đổi mảng được truyền vào. Bạn sẽ có tùy chọn để sao chép mảng và làm việc trên mảng ban đầu, tức là int[] sorted = array.clone();
Nhưng đây chỉ là một ví dụ về mã ngắn. Thời gian chạy là O(NlogN)trong khi cách của bạn làO(N)


30
Tôi nghĩ rằng tôi sẽ ngạc nhiên nếu một containsphương thức sửa đổi mảng của tôi.
Zong

@ZongLi: Đây chỉ là một ví dụ cho OP.Updated OP nếu chúng ta soi mói
Cratylus

5
Từ javadoc của binarySearch (): "giá trị trả về sẽ là> = 0 nếu và chỉ khi tìm thấy khóa." vì vậy Arrays.binarySearch (array, key)> = 0 nên được trả về!
icza

Bổ sung: Giá trị trả về của binarySearch () là (- (điểm chèn) - 1) nếu không chứa khóa mà có thể là giá trị khác -1.
icza

Điều này không thể -1xảy ra nếu nó có ý định thành sự thật. "Điểm chèn được định nghĩa là điểm mà tại đó khóa sẽ được chèn vào danh sách: chỉ mục của phần tử đầu tiên lớn hơn khóa hoặc list.size () nếu tất cả các phần tử trong danh sách nhỏ hơn khóa được chỉ định. ". Cần phải nói >= 0.
Brian

17

Tôi biết là quá muộn, nhưng hãy thử Integer[]thay vì int[].


Đây là giải pháp.
Atheesh27

Ủng hộ cho câu trả lời hiệu quả, Cảm ơn Willy
ucMedia

1

1. sử dụng một lần

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

2. sử dụng HashSet để xem xét hiệu suất nếu bạn sử dụng nhiều lần.

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

1

Thử cái này:

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

Bạn có thể chuyển đổi mảng int nguyên thủy của mình thành một danh sách mảng các Số nguyên bằng cách sử dụng mã Java 8 bên dưới,

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

Và sau đó sử dụng contains()phương pháp để kiểm tra xem danh sách có chứa một phần tử cụ thể hay không,

boolean containsElement = arrayElementsList.contains(key);

0

cái này hoạt động trong java 8

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

Nó sẽ ngay lập tức trở lại vào trận đấu đầu tiên, thay vào đó, nó sẽ vẫn quét tất cả các mục trong mảng, ngay cả khi nó đã tìm thấy kết quả phù hợp. (Hãy xem xét một mảng các mặt hàng trilion)
TriCore

Bạn đã đúng, hãy thử công khai này boolean tĩnh chứa (mảng int [] cuối cùng, khóa int cuối cùng) {return Arrays.stream (mảng) .anyMatch (n-> n == key); }
Farhad Baghirov

Java 8 stream anyMatch là một hoạt động ngắn mạch và sẽ không quét tất cả các mục trong mảng.
LordParsley

@LordParsley Mục tiêu của đoạn mã trên là kiểm tra phần tử trong mảng, không phải quét tất cả phần tử của mảng.
Farhad Baghirov

Xin lỗi, tôi thấy câu trả lời đã được chỉnh sửa. Tôi chỉ nhắc lại nó là đúng vì nó sẽ không cần phải quét tất cả nếu nó tìm thấy một phần.
LordParsley

0

Bạn có thể sử dụng java.util.Arrayslớp để biến đổi mảng T[?]trong một List<T>đối tượng bằng các phương thức như contains:

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

-1

Tùy thuộc vào độ lớn mảng int của bạn, bạn sẽ nhận được hiệu suất tốt hơn nhiều nếu bạn sử dụng các bộ sưu tập và .containsthay vì lặp lại từng phần tử trong mảng một:

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

Giải pháp # 1

Vì câu hỏi ban đầu chỉ muốn một giải pháp đơn giản hóa (chứ không phải một giải pháp nhanh hơn), đây là giải pháp một dòng:

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

Giải thích: Javadoc cho Arrays.toString()biết kết quả được đặt trong dấu ngoặc vuông và các phần tử liền kề được phân tách bằng các ký tự "," (dấu phẩy theo sau bởi dấu cách). Vì vậy, chúng ta có thể tin tưởng vào điều này. Đầu tiên, chúng tôi chuyển đổi arraythành một chuỗi, và sau đó chúng tôi kiểm tra xem keycó chứa trong chuỗi này hay không. Tất nhiên, chúng tôi không thể chấp nhận "số phụ" (ví dụ: "1234" chứa "23"), vì vậy chúng tôi phải tìm kiếm các mẫu trong đókey đứng trước dấu ngoặc mở hoặc dấu cách và theo sau là dấu ngoặc đóng hoặc dấu phẩy.

Lưu ý: Mẫu regexp được sử dụng cũng xử lý các số âm đúng cách (có biểu diễn chuỗi bắt đầu bằng dấu trừ).

Giải pháp # 2

Giải pháp này đã được đăng nhưng nó có sai sót, vì vậy tôi đăng giải pháp chính xác:

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

Ngoài ra giải pháp này có một tác dụng phụ: nó sửa đổi array(sắp xếp nó).


String handlig nói chung là đắt, tại sao ai đó lại coi int là chuỗi?
chối Vitali

@DenysVitali Vì op đã có một giải pháp hoạt động hiệu quả và anh ấy đang tìm kiếm một giải pháp ngắn hơn . Và chúng ngắn hơn. Câu hỏi này không phải về hiệu suất.
icza

Tôi cần phải có hiểu lầm câu hỏi sau đó, xin lỗi cho hỏi
Denys Vitali

-5

Cố gắng Integer.parseInt()làm điều này .....

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;

              }


     }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.