Let's assume the following array of integers:
int[] numbers = {4, 5, 1, 3, 7, 4, 1};
Since this is an array of primitives, the solution can simply loop the array and return to the first occurrence of the given integer, as follows:
public static boolean containsElement(int[] arr, int toContain) {
for (int elem: arr) {
if (elem == toContain) {
return true;
}
}
return false;
}
Another solution to this problem can rely on the Arrays.binarySearch() methods. There are several flavors of this method, but in this case, we need this one: int binarySearch​(int[] a, int key). The method will search the given key in the given array and will return the corresponding index or a negative value. The only issue is that this method works only for sorted arrays; therefore, we need to sort the array beforehand:
public static boolean containsElement(int[] arr, int toContain) {
Arrays.sort(arr);
int index = Arrays.binarySearch(arr, toContain);
return (index >= 0);
}
In Java 8, the solution can rely on a functional style approach. A good candidate here is the anyMatch() method. This method returns whether any elements of the stream match the predicate provided. So, all we need to do is to convert the array to a stream, as follows:
public static boolean containsElement(int[] arr, int toContain) {
return Arrays.stream(arr)
.anyMatch(e -> e == toContain);
}
For any other primitive type, it is pretty straightforward to adapt or generalize the preceding examples.
Now, let's focus on finding Object in arrays. Let's consider the Melon class:
public class Melon {
private final String type;
private final int weight;
// constructor, getters, equals() and hashCode() skipped for brevity
}
Next, let's consider an array of Melon:
Melon[] melons = new Melon[] {new Melon("Crenshaw", 2000),
new Melon("Gac", 1200), new Melon("Bitter", 2200)
};
Now, let's assume that we want to find the Gac melon of 1,200 g in this array. A solution can rely on the equals() method, which is used to determine the equality of two objects:
public static <T> boolean
containsElementObject(T[] arr, T toContain) {
for (T elem: arr) {
if (elem.equals(toContain)) {
return true;
}
}
return false;
}
If this method lives in a utility class named ArraySearch, then the following call will return true:
// true
boolean found = ArraySearch.containsElementObject(
melons, new Melon("Gac", 1200));
This solution works fine as long as we want to rely on the equals() contract. But we may consider that our melon is present in the array if its name occurs (Gac), or if its weight occurs (1,200). For such cases, it is more practical to rely on a Comparator:
public static <T> boolean containsElementObject(
T[] arr, T toContain, Comparator<? super T> c) {
for (T elem: arr) {
if (c.compare(elem, toContain) == 0) {
return true;
}
}
return false;
}
Now, a Comparator that takes into account only the type of melons can be written as follows:
Comparator<Melon> byType = Comparator.comparing(Melon::getType);
Since the Comparator ignores the weight of the melon (there is no melon of 1,205 grams), the following invocation will return true:
// true
boolean found = ArraySearch.containsElementObject(
melons, new Melon("Gac", 1205), byType);
Another approach relies on another flavor of binarySearch(). The Arrays class provides a binarySearch() method that gets a Comparator, <T> int binarySearch(T[] a, T key, Comparator<? super T> c). This means that we can use it as follows:
public static <T> boolean containsElementObject(
T[] arr, T toContain, Comparator<? super T> c) {
Arrays.sort(arr, c);
int index = Arrays.binarySearch(arr, toContain, c);
return (index >= 0);
}
Now, a Comparator that takes into account only the weight of melons can be written as follows:
Comparator<Melon> byWeight = Comparator.comparing(Melon::getWeight);
Since the Comparator ignores the type of melon (there is no melon of the Honeydew type), the following invocation will return true:
// true
boolean found = ArraySearch.containsElementObject(
melons, new Melon("Honeydew", 1200), byWeight);