views:

9183

answers:

8

How could I go about detecting (returning true/false) whether an ArrayList contains more than one of the same element in Java?

Many thanks, Terry

Edit Forgot to mention that I am not looking to compare "Blocks" with each other but their integer values. Each "block" has an int and this is what makes them different. I find the int of a particular Block by calling a method named "getNum" (e.g. table1[0][2].getNum();

+18  A: 

Simplest: dump the whole collection into a Set (using the Set(Collection) constructor or Set.addAll), then see if the Set has the same size as the ArrayList.

List<Integer> list = ...;
Set<Integer> set = new HashSet<Integer>(list);

if(set.size() < list.size()){
    /* There are duplicates */
}

Update: If I'm understanding your question correctly, you have a 2d array of Block, as in

Block table[][];

and you want to detect if any row of them has duplicates?

In that case, I could do the following, assuming that Block implements "equals" and "hashCode" correctly:

for (Block[] row : table) {
   Set set = new HashSet<Block>(); 
   for (Block cell : row) {
      set.add(cell);
   }
   if (set.size() < 6) { //has duplicate
   }
}

I'm not 100% sure of that for syntax, so it might be safer to write it as

for (int i = 0; i < 6; i++) {
   Set set = new HashSet<Block>(); 
   for (int j = 0; j < 6; j++)
    set.add(table[i][j]);

...

Paul Tomblin
Make sure to implement hashCode/equals as well.
jon077
Or even a bit easier: wrap it when creating the set, e.g. new HashSet(list), instead of using addAll.
Fabian Steeg
@jon077: That depends on your definition of "duplicate".
Michael Myers
Would the process of detecting the elements in a 2D array be the same?For example, checking from array[0][0] to array[0][6] (a 'row')..?Many thanks,Terry
Each object in the array holds an integer value. By "duplicate", the object would have the same integer value.
Terry, there are probably more efficient ways, but yes, you could add the array to a Set and compare Set.size to array.length.
Paul Tomblin
"Duplicate" has multiple meanings for objects (as opposed to primitives). If you're just using ints, or the Integer class which implements equals(), that shouldn't be an issue.
Nikhil Chelliah
I'm trying to implement the solution above but it seems to be triggering an error message which says: "myFile.java uses unchecked or unsafe operations"Not quite sure what it meansor what to do!
I think we'd have to see the code you actually wrote. The snippet in the answer isn't intended to compile as written, but what was written, should compile fine, provided you filled in the bits well.
Paul Brinkley
Sorry for the formatting, it didn't come out as expcted!
You can't turn a table into a list like that. Look at the Arrays class.
Paul Tomblin
If you're trying to turn the entire 36 Block objects into a single list, you need to loop.
Paul Tomblin
Comments aren't a good place to solve a secondary problem like this. Edit your question and I'll edit the answer, or ask a new question.
Paul Tomblin
Ah, I see that a "table" is a different thing entirely. Assume that "table1" is the name given to 2D array of "Block" objects
Sorry about the clutter in the comments, I've now edited my question. Thank you for the help so far!
Ok, so from what I can tell, the loops add each 'row' to a Set.So am i correct in thinking that now all that remains to do is compare each Set to the size of table1 (and if Set's size is less than the size of table1's size then there are duplicates)?
You said you wanted to find out if there were any duplicates *within* a row, not over the whole table. That's why I compare the set.size() to 6.
Paul Tomblin
Update: Solution implemented and working!Thank you all for your input on this problem and special thanks to Paul for going out of your way to help!Warm Regards,Terry
+7  A: 

If you are looking to avoid having duplicates at all, then you should just cut out the middle process of detecting duplicates and use a Set.

matt b
Make sure to implement hashCode/equals :)
jon077
@jon077: Not necessarily, as I just said.
Michael Myers
+4  A: 

If your elements are somehow Comparable (the fact that the order has any real meaning is indifferent -- it just needs to be consistent with your definition of equality), the fastest duplicate removal solution is going to sort the list ( 0(n log(n)) ) then to do a single pass and look for repeated elements (that is, equal elements that follow each other) (this is O(n)).

The overall complexity is going to be O(n log(n)), which is roughly the same as what you would get with a Set (n times long(n)), but with a much smaller constant. This is because the constant in sort/dedup results from the cost of comparing elements, whereas the cost from the set is most likely to result from a hash computation, plus one (possibly several) hash comparisons. If you are using a hash-based Set implementation, that is, because a Tree based is going to give you a O( n log²(n) ), which is even worse.

As I understand it, however, you do not need to remove duplicates, but merely test for their existence. So you should hand-code a merge or heap sort algorithm on your array, that simply exits returning true (i.e. "there is a dup") if your comparator returns 0, and otherwise completes the sort, and traverse the sorted array testing for repeats. In a merge or heap sort, indeed, when the sort is completed, you will have compared every duplicate pair unless both elements were already in their final positions (which is unlikely). Thus, a tweaked sort algorithm should yield a huge performance improvement (I would have to prove that, but I guess the tweaked algorithm should be in the O(log(n)) on uniformly random data)

Varkhan
In this case, n is 6 so I wouldn't waste a lot of time on implementation details, but I'll keep your idea of the special heap sort if I ever need to do something like that.
Paul Tomblin
A: 

Simply put: 1) make sure all items are comparable 2) sort the array 2) iterate over the array and find duplicates

Antonio
+2  A: 

Improved code, using return value of Set#add instead of comparing the size of list and set.

public static <T> boolean hasDuplicate(Collection<T> list) {
    Set<T> set = new HashSet<T>();
    // Set#add returns false if the set does not change, which
    // indicates that a duplicate element has been added.
    for (T each: list) if (!set.add(each)) return true;
    return false;
}
Adrian
A: 

Sir adrian wht do u mean by T can pls make it more simplier?? im just new in java..i really want to know how to use ur kind of methods

thank you!

A: 
+1  A: 

The real answer is to learn what the different types of collections actually are.

  • List - ordered, null is ok, duplicates ok
  • Set - may be ordered, null may be ok, duplicates are not ok.

To be sure read the Javadoc and learn what Queues and all the other types are.

mP