gaurav1207
gaurav1207

Reputation: 703

Checking value contained in java collection List

I have a List of long Arrays with the name Arraycells:

List<long[]> Arraycells = new ArrayList<>() ;
Arraycells.add(new long[]{1L, 0L});
Arraycells.add(new long[]{1L, 1L});
Arraycells.add(new long[]{1L, 2L});

I want to see if a long array object is contained in this list or not:

for (long r = 0L; r < 3; r++) {
    for (long c = 0L; c < 3; c++) {
        if (Arraycells.contains(new long[]{r, c})) { // problem is with this statement
            // do something
        }
    }
}

How can I check the Arraycells?

Upvotes: 4

Views: 116

Answers (3)

Oleksandr Pyrohov
Oleksandr Pyrohov

Reputation: 16216

You might want to try another variant using List<Long> instead of long[]:

List<List<Long>> cells = new ArrayList<>();
cells.add(Arrays.asList(1L, 0L));
cells.add(Arrays.asList(1L, 1L));
cells.add(Arrays.asList(1L, 2L));

for (long i = 0L; i < 3; i++) {
    for (long j = 0L; j < 3; j++) {
        if (cells.contains(Arrays.asList(i, j))) {
            System.out.println("Contains: " + i + ", " + j);
        }
    }
}

Also note, that code from your example checks reference equality, because arrays inherit equals from Object. On the other hand, List.equals(...) implementation checks whether lists contain the same elements and in the same order.

Upvotes: 1

Ousmane D.
Ousmane D.

Reputation: 56393

contains would not work here. you should use Arrays.equals for array comparison.

Try this:

for (long r = 0L ;r < 3;r++) {
    final long copyR = r;
    for (long c = 0L; c < 3; c++) {
         final long copyC = c;
         final long[] temp = new long[]{copyR, copyC};
         if (Arraycells.stream()
                       .anyMatch(e -> Arrays.equals(e, temp))){  
                    //do something 
         }
    }
}

We utilise the Stream::anyMatch method to search through the arrays and find any matching array with Arrays::equals.

Upvotes: 1

Mick Mnemonic
Mick Mnemonic

Reputation: 7956

Java is an object-oriented language, so you should prefer modeling the problem with a proper class instead of using a primitive array directly. This makes e.g. object equality comparisons easier, by encapsulating the logic in equals(). You cannot override equals() for primitive arrays.

So you could define

public class ArrayCell {

    private final long[] content;

    public ArrayCell(long[] content) {
        this.content = content;
    }

    @Override
    public boolean equals(Object another) {
        if (another == null || another.getClass() != this.getClass()) {
            return false;
        }
        return Arrays.equals(this.content, another.content);
    }
    @Override
    public int hashCode() {
        return Objects.hash(content);
    }         
}

And the client code becomes:

List<ArrayCell> cells = new ArrayList<>() ;
cells.add(new ArrayCell(new long[]{1L, 0L}));
cells.add(new ArrayCell(new long[]{1L, 1L}));
cells.add(new ArrayCell(new long[]{1L, 2L}));

for (long r = 0L; r < 3; r++){
    for (long c = 0L; c < 3; c++){
        if(cells.contains(new ArrayCell(new long[]{r,c}))){
            // contains calls ArrayCell.equals() internally, so this will work
         }
    }
}

Upvotes: 1

Related Questions