check if List<int[]> contains a given int[] [duplicate] - java

This question already has answers here:
How can I find if my ArrayList of int[] contains an int[]
(4 answers)
Check if ArrayList contains an Array Object
(1 answer)
The best way to check if List<String[]> contains a String[] [duplicate]
(4 answers)
Closed 3 years ago.
How do I check if an ArrayList<int[]> contains a given array [x, y]? I have found the same question in c#, but can't find any answers for java.
At the moment I am using myList.contains(myArray) but it is always evaluating to false, I assume for similar reasons as in C#. The solution in C# is to use LINQ, which does not exist in java.
Is there another way I can do this or will I have to write my own subroutine to pull out the values of each list element and compare them manually?
Edit: I've written my own subroutine to do this which works (assuming each array has two elements), but a more elegant solution would be appreciated
private boolean contains(List<int[]> list, int[] array) {
for (int[] listItem : list) {
if (listItem[0] == array[0] &&
listItem[1] == array[1]) {
return true;
}
}
return false;

The .contains method compares each object with .equals which as this answer points out just compares the identity of the array objects (i.e. checks if they're the same Java object), it does not compare the contents of the arrays.
What you need to do is to write a for loop, check each element with Arrays.equals(..) (which compares the contents of the arrays). For example:
boolean found = false;
for (int i = 0; i < myList.size(); i++)
if (Arrays.equals(myArray, myList.get(i)) found = true;

There is Arrays.equals, and also Streams, which are designed for similar use cases as LINQ. In this case, the Stream.anyMatch method is very similar to Any in LINQ.
Combining these two, you can write your method in one statement:
private boolean contains(List<int[]> list, int[] array) {
return list.stream()
.anyMatch(x -> Arrays.equals(x, array));
}

Related

Compare two arrays with not the same order

I'm new in coding and I decided to learn java, groovy. I am making a simple exercise. I got a two array and I must compare them if they are equal. I take values from 2 database and these databases are same, but values are not in the same order, but they are equal. For example, I have:
ArrayList collection1 = ["test","a"]
ArrayList collection2 = ["a","test"]
Well I tried this:
assert collection1.equals(collection2)
But I know that this works only when values in those arrays are placed in same order.
I can think of two methods:
Check that they are equal sizes
Wrap the two arrays with Arrays.asList()
Check if a contains all elements from b
public static boolean equals(Object[] a, Object[] b) {
return a.length == b.length && Array.asList(a).containsAll(Arrays.asList(b));
}
Another way would be to just iterate over both arrays at once and then check if the elements are equal:
public static boolean equals(Object[] a, Object[] b) {
if(a.length != b.length) return false;
outer: for(Object aObject : a) {
for(Object bObject : b) {
if(a.equals(b)) continue outer;
}
return false;
}
return true;
}
Both methods are rather fast, the first introduces an additional wrapper around the arrays, but is neglectable as Arrays.asList() just uses the given array as a View and does not do any additional copying.
Now it seems that you're actually comparing two Collections, then you can just use this approach:
public static boolean equals(Collection<?> a, Collection<?> b) {
return a.size() == b.size() && a.containsAll(b);
}
In an array the order is important. If you want an array without checking the order, you should use Sets Sets tutorial.
However, if you don't want to use another type I suggest you implement your own function that checks the presence of each element in one another.
I hope this can helps !
I know absolutely zilch about Java programming, but I've thought of this problem more generally for some time and I think I have a workable solution that is generalizable if you know a priori all the values that can be contained in the array.
If you assign a prime number to each possible string that can be in the array and then multiply all the elements of an array together, then the multiplied number will represent a unique combination, but not order, or the elements of the array. To close the loop, then you just have to compare the values of that multiplication. If there's a better answer, use that, but I thought I would share this idea.
In Groovy, just sort them, and check the sorted lists:
assert listA.sort(false) == listB.sort(false)
Or if they can't have duplicates, use Sets as suggested by #Baldwin

Java 8 lambda expressions: Summing up method return values in a for each call for List/Set and Iterable [duplicate]

This question already has answers here:
How to sum a list of integers with java streams?
(12 answers)
Closed 5 years ago.
For an example, I have a list (or set) into which the same method is to be done for each entry. This is increadibly easy with a lamba as such:
ingredientBaskets.forEach(this::processToMarmalade);
However I would like for the processToMarmalade method to return the amount of fruit pieces that could not be processed and these summed up in the end. I can do that easily by having the method sum up and return the number of errors.
What I'd like to have is basically something like:
int result = ingredientBaskets.forEach(this::processToMarmalade).sum();
some something.
Or in other words something that does the same as this:
int result = 0;
for (final Basket basket: ingredientBaskets) {
result += processToMarmalade(basket)
}
}
Is there a way to do that?
EDIT: As from the answers, List and Set would allow the usage of IntStream, which is one thing that I need. What however, if it's Iterable? This one does not have a stream, just a forEach.
Assume the original question, but also for the case of Iterable. Can the forEach sum it all up someway, or do I have to create a new List and fill it up with the contents of the Iterable first?
What you are looking for is the mapToInt method (assuming processToMarmalade returns an int):
int result = ingredientBaskets.stream().mapToInt(this::processToMarmalade).sum();
If ingredientBaskets you have is an Iterable<?>, you can convert it to a stream like this:
StreamSupport.stream(ingredientBaskets.spliterator(), false)
.mapToInt(this::processToMarmalade)
.sum();
ingredientBaskets.stream()
.mapToInt(this::processToMarmalade)
.sum()
I guess I would do it like this:
ingredientBaskets.stream().mapToInt(this::processToMarmalade).sum();

Sorting a 2D array by the [i][2] element [duplicate]

This question already has answers here:
Sort a two dimensional array based on one column
(8 answers)
Closed 5 years ago.
Assume I have this 2D array:
array[0][] = {5,B,2}
array[1][] = {9,R,4}
array[2][] = {3,B,1}
array[3][] = {1,R,8}
How can I sort this array in such a way that this is the output:
array[0][] = {3,B,1}
array[1][] = {5,B,2}
array[2][] = {9,R,4}
array[3][] = {1,R,8}
Basically sorting them based on the [i][2] element.
This is how I declared the array:
String[][] splitnodes = new String[7][];
Is it even possible? If it is, how?
Thanks!
One approach would be to implement a "normal search" like insertion sort, where you only compare the second element, and then carry the rest of the elements
You can use any sorting tecnique and in the step involving the comparision you need to compare the 2nd element of each sub array. Using the utility method provided in the J0DK you may also use sortmethod defined in Arrays.java.
java.util.Arrays.sort(array, new
java.util.Comparator<String[]> () {
public int compare(String[] a, String[] b) {
return Integer.compare(Integer.parseInt( a[2]), Integer.parseInt(b[2]));
}
});

initialisation of array cause for loop to be null [duplicate]

This question already has answers here:
Removing empty element from Array(Java)
(5 answers)
Closed 6 years ago.
I'm trying to remove a specific character from an array by copying the non specified elements into a new array. However, when I initialize new array, the return value is giving me a bunch of null values instead of the non specified element array.
public String[] wordsWithout(String[] words, String target) {
String store[] = null;
for(int i = 0; i < words.length; i = i +1){
store = new String[words.length];
if(!words[i].equals(target)){
store[i] = words[i];
}
}
return store;
}
You are initializing the result array inside the loop. In other words, for each iteration of the loop, you initialize a new array, and lose the changes you made to the previous one. You should move the initialization outside the loop.
But that would also pose a problem, as you wouldn't be able to preemptively know the size of the resulting array. Java 8 allows you a much easier way to write such a method:
public String[] wordsWithout(String[] words, String target) {
return Arrays.stream(words)
.filter(w -> !w.equals(target))
.toArray(String[]::new);
}
EDIT:
As noted in the comments, the design of the OP could be preserved, and the results could be accumulated in a List. IMHO, it's less elegant, but it would work in older versions of Java too:
public String[] wordsWithout(String[] words, String target) {
List<String> store = new ArrayList<>();
for (String word : words) {
if (!word.equals(target)){
store.add(word);
}
}
return store.toArray(new String(store.size());
}
You are initializing the array each time in for loop. Please check.
This is happening because you have of this line: store = new String[words.length]. This means that you are initializing your new Array to an Array of words.length elements all of them being initialized by default with null.
The other problem I see is that you are initializing your Array inside the loop, so at each iteration you will overwrite the changes you have already made in the previous loop (if made any)
To copy the non-specified elements in your new array I will do like #Mureinik mentioned above.

Coverting a Boolean object array to boolean primitive array? [duplicate]

This question already has answers here:
Converting an array of objects to an array of their primitive types
(9 answers)
Closed 4 years ago.
I have an ArrayList of type Boolean that requires to be manipulated as a boolean[] as I am trying to use:
AlertDialog builder;
builder.setMultiChoiceItems(items, checkedItems, new DialogInterface.OnMultiChoiceClickListener() { ... });
However, while I can create a Boolean object array, I cannot find an efficient way to covert this object array to a primitive array that the builder function calls for (the only method I can come up with is to iterate over the Object array and build a new primitive array).
I am retrieving my Object array from the ArrayList as follows:
final Boolean[] checkedItems = getBoolList().toArray(new Boolean[getBoolList().size()]);
Is there something I can do with my ArrayList? Or is there an obvious casting/conversion method that I am missing??
Any help appreciated!
You aren't missing anything, the only way to do it is to Iterate over the list I'm afraid
An (Untested) Example:
private boolean[] toPrimitiveArray(final List<Boolean> booleanList) {
final boolean[] primitives = new boolean[booleanList.size()];
int index = 0;
for (Boolean object : booleanList) {
primitives[index++] = object;
}
return primitives;
}
Edit (as per Stephen C's comment):
Or you can use a third party util such as Apache Commons ArrayUtils:
http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/ArrayUtils.html
Using Guava, you can do boolean[] array = Booleans.toArray(getBoolList());.

Categories

Resources