I have list of ObjectLocation, declared as
List<ObjectLocation> myLocations;
And here's how ObjectLocation looks like:
public class ObjectLocation {
int locationID, ratingCount = 0;
}
Ok now myLocations holds thousands of locationID. If I have a particular locationID, how do I search the contents of myLocations for the locationID, and get the searched locationID's index (within myLocations) and it's ratingCount?
Well, you loop through all of the elements in the list, and if the locationID match, you've found your element!
int idx=0;
for (ObjectLocation ol:myLocations){
if (ol.locationID==searchedLocationID){
// found at index idx!!
}
idx++;
}
More efficiently, you could have a Map<Integer,ObjectLocation> where the key is the locationID of the ObjectLocation, to get much faster lookups.
For this sort of lookup I'd switch to using a Map<Integer, ObjectLocation> and store entries in the map like this:
Map<Integer, List<ObjectLocation>> myLocationMap = new HashMap<>();
List<ObjectLocation> currentList = myLocationMap.get(oneLocation.locationID);
if(currentList == null) {
// We haven't stored anything at this locationID yet,
// so create a new List and add it to the Map under
// this locationID value.
currentList = new ArrayList<>();
myLocationMap.put(oneLocation.locationID, currentList);
}
currentList.add(oneLocation);
Now you can quickly get all of the ObjectLocation entries with a specific value for locationID by grabbing them from the map like this:
List<ObjectLocation> listOfLocations = myLocationMap.get(someLocationId);
This assumes that multiple ObjectLocation instances can have the same locationID value. If not then you wouldn't need a List<ObjectLocation> in the map, just a single ObjectLocation.
For you to easily search and find a your ObjectLocation objects, you should first define .equals(Object o) method, in ObjectLocation class, that allows one ObjectLocation to be compared to another. After that, all you have to do is use .indexOf(Object o)' to get the index of the ObjectLocation you are looking for. Then extract that object and use its information as exemplified in the code below:
public class ObjectLocation {
int locationID, ratingCount = 0;
public boolean equals(Object o)
{
if(!(o instanceof ObjectLocation))
return false;
ObjectLocation another = (ObjectLocation)o;
if( locationID == another.locationID && ratingCount == another.ratingCount)
return true;
else
return false;
}
public static void main(String[] args)
{
List<ObjectLocation> myLocations;
ObjectLocation findThisLocation;
ObjectLocation found;
//Additional code here
int index = myLocations.indexOf(findThisLocation);
found = myLocations.get(index);
int id = found.locationID;
int rating = found.ratingCount;
}
}
List<ObjectLocation> myLocations = new ArrayList<>();
int index =0;
int particularId = 1;//!your Id
int locationid = 0;
int ratingcount = 0;
for(int i =0; i < myLocations.size(); i++) {
if(myLocations.get(i).locationID == particularId) {
index = i;
locationid = myLocations.get(i).locationID;
ratingcount = myLocations.get(i).ratingCount;
}
}
For Java 8, I would use (without changing anything on the data structure like using a Map instead or knowing about ordering in the list):
Optional<ObjectLocation> found = myLocations.stream()
.filter(location -> location.locationID == particularLocationID)
.findAny();
if (found.isPresent() {
int ratingCount = found.get();
…
}
When you need more performance for single searches, you may try parallelStream() instead of stream().
Related
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();
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]);
...
Set.add returns a boolean false if the item being added is already in the set, so you could even short circuit and bale out on any add that returns false if all you want to know is whether there are any duplicates.
Improved code, using return value of Set#add instead of comparing the size of list and set.
public static <T> boolean hasDuplicate(Iterable<T> all) {
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: all) if (!set.add(each)) return true;
return false;
}
With Java 8+ you can use Stream API:
boolean areAllDistinct(List<Block> blocksList) {
return blocksList.stream().map(Block::getNum).distinct().count() == blockList.size();
}
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.
Improved code to return the duplicate elements
Can find duplicates in a Collection
return the set of duplicates
Unique Elements can be obtained from the Set
public static <T> List getDuplicate(Collection<T> list) {
final List<T> duplicatedObjects = new ArrayList<T>();
Set<T> set = new HashSet<T>() {
#Override
public boolean add(T e) {
if (contains(e)) {
duplicatedObjects.add(e);
}
return super.add(e);
}
};
for (T t : list) {
set.add(t);
}
return duplicatedObjects;
}
public static <T> boolean hasDuplicate(Collection<T> list) {
if (getDuplicate(list).isEmpty())
return false;
return true;
}
I needed to do a similar operation for a Stream, but couldn't find a good example. Here's what I came up with.
public static <T> boolean areUnique(final Stream<T> stream) {
final Set<T> seen = new HashSet<>();
return stream.allMatch(seen::add);
}
This has the advantage of short-circuiting when duplicates are found early rather than having to process the whole stream and isn't much more complicated than just putting everything in a Set and checking the size. So this case would roughly be:
List<T> list = ...
boolean allDistinct = areUnique(list.stream());
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)
If you want the set of duplicate values:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class FindDuplicateInArrayList {
public static void main(String[] args) {
Set<String> uniqueSet = new HashSet<String>();
List<String> dupesList = new ArrayList<String>();
for (String a : args) {
if (uniqueSet.contains(a))
dupesList.add(a);
else
uniqueSet.add(a);
}
System.out.println(uniqueSet.size() + " distinct words: " + uniqueSet);
System.out.println(dupesList.size() + " dupesList words: " + dupesList);
}
}
And probably also think about trimming values or using lowercase ... depending on your case.
Simply put:
1) make sure all items are comparable
2) sort the array
2) iterate over the array and find duplicates
To know the Duplicates in a List use the following code:It will give you the set which contains duplicates.
public Set<?> findDuplicatesInList(List<?> beanList) {
System.out.println("findDuplicatesInList::"+beanList);
Set<Object> duplicateRowSet=null;
duplicateRowSet=new LinkedHashSet<Object>();
for(int i=0;i<beanList.size();i++){
Object superString=beanList.get(i);
System.out.println("findDuplicatesInList::superString::"+superString);
for(int j=0;j<beanList.size();j++){
if(i!=j){
Object subString=beanList.get(j);
System.out.println("findDuplicatesInList::subString::"+subString);
if(superString.equals(subString)){
duplicateRowSet.add(beanList.get(j));
}
}
}
}
System.out.println("findDuplicatesInList::duplicationSet::"+duplicateRowSet);
return duplicateRowSet;
}
best way to handle this issue is to use a HashSet :
ArrayList<String> listGroupCode = new ArrayList<>();
listGroupCode.add("A");
listGroupCode.add("A");
listGroupCode.add("B");
listGroupCode.add("C");
HashSet<String> set = new HashSet<>(listGroupCode);
ArrayList<String> result = new ArrayList<>(set);
Just print result arraylist and see the result without duplicates :)
This answer is wrriten in Kotlin, but can easily be translated to Java.
If your arraylist's size is within a fixed small range, then this is a great solution.
var duplicateDetected = false
if(arrList.size > 1){
for(i in 0 until arrList.size){
for(j in 0 until arrList.size){
if(i != j && arrList.get(i) == arrList.get(j)){
duplicateDetected = true
}
}
}
}
private boolean isDuplicate() {
for (int i = 0; i < arrayList.size(); i++) {
for (int j = i + 1; j < arrayList.size(); j++) {
if (arrayList.get(i).getName().trim().equalsIgnoreCase(arrayList.get(j).getName().trim())) {
return true;
}
}
}
return false;
}
String tempVal = null;
for (int i = 0; i < l.size(); i++) {
tempVal = l.get(i); //take the ith object out of list
while (l.contains(tempVal)) {
l.remove(tempVal); //remove all matching entries
}
l.add(tempVal); //at last add one entry
}
Note: this will have major performance hit though as items are removed from start of the list.
To address this, we have two options. 1) iterate in reverse order and remove elements. 2) Use LinkedList instead of ArrayList. Due to biased questions asked in interviews to remove duplicates from List without using any other collection, above example is the answer. In real world though, if I have to achieve this, I will put elements from List to Set, simple!
/**
* Method to detect presence of duplicates in a generic list.
* Depends on the equals method of the concrete type. make sure to override it as required.
*/
public static <T> boolean hasDuplicates(List<T> list){
int count = list.size();
T t1,t2;
for(int i=0;i<count;i++){
t1 = list.get(i);
for(int j=i+1;j<count;j++){
t2 = list.get(j);
if(t2.equals(t1)){
return true;
}
}
}
return false;
}
An example of a concrete class that has overridden equals() :
public class Reminder{
private long id;
private int hour;
private int minute;
public Reminder(long id, int hour, int minute){
this.id = id;
this.hour = hour;
this.minute = minute;
}
#Override
public boolean equals(Object other){
if(other == null) return false;
if(this.getClass() != other.getClass()) return false;
Reminder otherReminder = (Reminder) other;
if(this.hour != otherReminder.hour) return false;
if(this.minute != otherReminder.minute) return false;
return true;
}
}
ArrayList<String> withDuplicates = new ArrayList<>();
withDuplicates.add("1");
withDuplicates.add("2");
withDuplicates.add("1");
withDuplicates.add("3");
HashSet<String> set = new HashSet<>(withDuplicates);
ArrayList<String> withoutDupicates = new ArrayList<>(set);
ArrayList<String> duplicates = new ArrayList<String>();
Iterator<String> dupIter = withDuplicates.iterator();
while(dupIter.hasNext())
{
String dupWord = dupIter.next();
if(withDuplicates.contains(dupWord))
{
duplicates.add(dupWord);
}else{
withoutDupicates.add(dupWord);
}
}
System.out.println(duplicates);
System.out.println(withoutDupicates);
A simple solution for learners.
//Method to find the duplicates.
public static List<Integer> findDublicate(List<Integer> numList){
List<Integer> dupLst = new ArrayList<Integer>();
//Compare one number against all the other number except the self.
for(int i =0;i<numList.size();i++) {
for(int j=0 ; j<numList.size();j++) {
if(i!=j && numList.get(i)==numList.get(j)) {
boolean isNumExist = false;
//The below for loop is used for avoid the duplicate again in the result list
for(Integer aNum: dupLst) {
if(aNum==numList.get(i)) {
isNumExist = true;
break;
}
}
if(!isNumExist) {
dupLst.add(numList.get(i));
}
}
}
}
return dupLst;
}
Class Order
{
String name;
Order(String n)
{ name = n; }
//setter and getters of name
}
Order a = new Order("same");
Order b = new Order("same");
Order c = new Order("diff");
List<Order> nameList// a,b,c
I want to
seperate list of Orders
List<Order> dupList// a,b
List<Order> nondupList// c
Now I want to check whether same name is available in multiple orders of "nameList".
I achieved that using index of List and compare with other than that index List Orders.
But is there any other better way to achieve this.
Probably one other way could be - Override hashCode method and equals method. Generate hasCode on calculation of string name.
public class Order {
String name;
public Order(String n) {
name = n;
}
// setter and getters of name
#Override
public int hashCode() {
int h = 0;
int len = name.length();
for (int i = 0; i < len; i++)
h = 31 * h + name.charAt(i);
return h;
}
#Override
public boolean equals(Object obj) {
if(obj == null)
return false;
else if(this.hashCode() == obj.hashCode())
return true;
return false;
}
}
...
List<Order> nameList = ...;// a,b,c
Set<Order> nonDuplicate= new HashSet<Order>(nameList);
If you want to use pure java, add the elements to the a List, and sort it with the appropriate comparator. Then iterate over the list, keeping track of the previous element, doing a control break; in other words, if the element is the same as the previous both are a duplicate. If they are not (or it is the first), they are a candidate and you need to wait for the next check to find a duplicate.
If you don't want to sort, you can add the elements to a Set as they appear; if before adding an element it is already in the set, you can add it to the duplicate set. You can do the check on both sets removing as you go, or remove from the complete set the duplicates at the end. You can use any collection, but Set is more efficient since it has a fast contains method.
If you can use libraries, you can just use Guava and add everything to a multiset (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multiset.html ) Then iterate over the multiset and you have the count per element.
You could use Map>, get list for given name, if null, create it and put it in, add current order in that list.
i having an object with below information
TransHdr: id, order_num
TransItem: hdr_id, product_code, refnum, qty (child record)
transHdr.id=transItem.hdr_id
if let say 3 record can be found in TransItem,
parkA,112,10
parkA,112,6
parkB,113,10
i would like group it base on refnum, means that my result will be
parkA,112,16
parkB,113,10
i need a method that will loop the object (item level) and need to return transHdr object to other function. anyway to do this?
for (java.util.Iterator<ITransItem> groupTransItems = TransHdr.getTransItems().iterator();
groupTransItems.hasNext();) {
ITransItem _TransItem = groupTransItems.next();
if (null!=_TransItem.getRefNum()){
<question here..how do i group and sum up my item and become only 1 record?>
}
}
return newGroupingTransHdr;
}
Create a new Map with refnum as key and qty as value.
Map<String,Integer> qtyMap=new HashMap<String,Integer>();
while iterating, try
String refNum=transItem.getRefNum();
// Mark for removal ? if this is not the first item in the list with the refnum
boolean remove=true;
Integer currentQty=qtyMap.get(refNum);
if(currentQty==null){
currentQty=0;
// this doesnt exist already in the map, this is the first item with this reference
// number in the list, so you should keep this without removing
remove=false;
}
currentQty=currentQty+transItem.getQty();
qtyMap.put(refNum,currentQty);
// if the remove is true then remove this item from the list.
if(remove){
groupTransItems.remove();
}
This will sum up the qty for refnum's in the map and once your iteration is over, the map will have the sums of quantities for each refnum. You will have to iterate the list once more to set the current qty to each item from the map [EDIT] :- Added the iterating time removal.
Similar to the solution suggested in this post. You can have a Map with ref_num as key and TransItem as value.
TransHdr transHdr; // Externally given
Map<String, ITransItem> collapsedItems = new HashMap<String, ITransItem>();
List<ITransItem> items = transHdr.getItems();
transHdr.setItems(new ArrayList<ItransItem>());
for (ITransItem item : items) {
String ref_num = item.getRefNum();
ITransItem collapsedItem = collapsedItems.get(ref_num);
if (collapsedItem == null) {
collapsedItems.put(ref_num, item);
} else {
int qnt = item.getQnt();
collapsedItem.setQnt(collapsedItem.getQunt() + qnt);
}
}
transHdr.setItems(new ArrayList<ITransItem>(collapsedItems.values()));
Another way to accomplish what you want to do is to embed the logic in an add method on your TransHdr class.
pulic class TransHdr {
private String id;
private int orderNumber;
private Map<String, ITransItem> items;
public TransHdr(String id, int orderNumber) {
this.id = id;
this.orderNumber = orderNumber;
this.items = new HashMap<String, ITransItem>();
}
public void addItem(ITransItem item) {
String ref = item.getRefNum();
ITransItem currentItem = items.get(ref);
if (currentItem == null) {
items.put(ref, item);
} else {
int qnt = item.getQnt();
currentItem.setQnt(currentItem.getQnt() + qnt);
}
}
public Set<ITransItem> getItems() {
return items.values();
}
}
As you can see, there's multiple ways of doing this. The appropriate solution depends on what your requirements and use cases are.
Suppose I have a custom object set up in a class similar to this.
public class anObject {
public String id, otherProperty;
public anObject(){
this.id = "1";
this.otherProperty = "cat";
}
}
Then I create an array of these objects in another class
anObject[] objects = new anObject[40];
for(int i=0; i < 40; i++){
objects[i] = new anObject();
}
What can I do then to find the first object in the array that has an id of 2 (for example)?
anObject found = null;
for(int i=0; i < 40; i++){
if ("2".equals(object[i].id)) {
// found it
found = object[i];
break; // exit the loop
}
}
Or am I missing something?
EDIT: added the break. Also, there is a convention that class names begin with an uppercase letter, such as AnObject.
There are multiple ways of going about this. First, you could do a simple for loop, iterating over all of the objects until one with a specific id is found. Your search complexity would be O(N)
anObject obj = null;
dance: for( int i = 0; i < objects.length; i++ )
{
if( object[i].id == 2 )
{
obj = object[i];
break dance;
}
}
if you know that you're always going to be searching by id, you could implement Comparable. Then you can use java.util.Arrays to sort and search the array for you. This reduces your search to O(log n)
public class anObject implements Comparable {
public String id, otherProperty;
public anObject(){
this.id = "1";
this.otherProperty = "cat";
}
public int compareTo( Object o )
{
if( o instanceof anObject )
{
return this.id.compareTo( ( (anObject) other).id );
}
return -1;
}
}
Last option, you can store the results in a Map<String, anObject>. If you're doing a lot of searching, this is the best method as it gives your search O(1), at the cost of additional memory.
There's no other way besides iterating through them and checking manually, as Matthew showed you. You can store them in the order of the id and do something like binary search to cut down time to O(log(n)) instead of O(n), but that might be too much overhead.
You can try storing them in a Map<String, YourObject> and just do map.get(id). This has O(1) access time.
Map<String, YourObject> map = new HashMap<String, YourObject>();
for (int i=0; i < 40; i++) {
YourObject obj = new YourObject(); // couldn't put anObject, it bugged me :)
map.put(obj.id, obj);
}
// get object with id = 2
YourObject secondOne = map.get("2");
if (secondOne != null) {
...
}
The best way to do this depends your main use-cases, really, and on how many elements you plan on supporting.
public static anObject findById(anObject[] arr,String str) {
for (anObject obj:arr) if (obj.id.equals(str)) return obj;
return null;
}
And then call anObject.findById(objects,"2")
Use Commons Collections:
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html#find(java.util.Collection, org.apache.commons.collections.Predicate)
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();
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]);
...
Set.add returns a boolean false if the item being added is already in the set, so you could even short circuit and bale out on any add that returns false if all you want to know is whether there are any duplicates.
Improved code, using return value of Set#add instead of comparing the size of list and set.
public static <T> boolean hasDuplicate(Iterable<T> all) {
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: all) if (!set.add(each)) return true;
return false;
}
With Java 8+ you can use Stream API:
boolean areAllDistinct(List<Block> blocksList) {
return blocksList.stream().map(Block::getNum).distinct().count() == blockList.size();
}
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.
Improved code to return the duplicate elements
Can find duplicates in a Collection
return the set of duplicates
Unique Elements can be obtained from the Set
public static <T> List getDuplicate(Collection<T> list) {
final List<T> duplicatedObjects = new ArrayList<T>();
Set<T> set = new HashSet<T>() {
#Override
public boolean add(T e) {
if (contains(e)) {
duplicatedObjects.add(e);
}
return super.add(e);
}
};
for (T t : list) {
set.add(t);
}
return duplicatedObjects;
}
public static <T> boolean hasDuplicate(Collection<T> list) {
if (getDuplicate(list).isEmpty())
return false;
return true;
}
I needed to do a similar operation for a Stream, but couldn't find a good example. Here's what I came up with.
public static <T> boolean areUnique(final Stream<T> stream) {
final Set<T> seen = new HashSet<>();
return stream.allMatch(seen::add);
}
This has the advantage of short-circuiting when duplicates are found early rather than having to process the whole stream and isn't much more complicated than just putting everything in a Set and checking the size. So this case would roughly be:
List<T> list = ...
boolean allDistinct = areUnique(list.stream());
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)
If you want the set of duplicate values:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class FindDuplicateInArrayList {
public static void main(String[] args) {
Set<String> uniqueSet = new HashSet<String>();
List<String> dupesList = new ArrayList<String>();
for (String a : args) {
if (uniqueSet.contains(a))
dupesList.add(a);
else
uniqueSet.add(a);
}
System.out.println(uniqueSet.size() + " distinct words: " + uniqueSet);
System.out.println(dupesList.size() + " dupesList words: " + dupesList);
}
}
And probably also think about trimming values or using lowercase ... depending on your case.
Simply put:
1) make sure all items are comparable
2) sort the array
2) iterate over the array and find duplicates
To know the Duplicates in a List use the following code:It will give you the set which contains duplicates.
public Set<?> findDuplicatesInList(List<?> beanList) {
System.out.println("findDuplicatesInList::"+beanList);
Set<Object> duplicateRowSet=null;
duplicateRowSet=new LinkedHashSet<Object>();
for(int i=0;i<beanList.size();i++){
Object superString=beanList.get(i);
System.out.println("findDuplicatesInList::superString::"+superString);
for(int j=0;j<beanList.size();j++){
if(i!=j){
Object subString=beanList.get(j);
System.out.println("findDuplicatesInList::subString::"+subString);
if(superString.equals(subString)){
duplicateRowSet.add(beanList.get(j));
}
}
}
}
System.out.println("findDuplicatesInList::duplicationSet::"+duplicateRowSet);
return duplicateRowSet;
}
best way to handle this issue is to use a HashSet :
ArrayList<String> listGroupCode = new ArrayList<>();
listGroupCode.add("A");
listGroupCode.add("A");
listGroupCode.add("B");
listGroupCode.add("C");
HashSet<String> set = new HashSet<>(listGroupCode);
ArrayList<String> result = new ArrayList<>(set);
Just print result arraylist and see the result without duplicates :)
This answer is wrriten in Kotlin, but can easily be translated to Java.
If your arraylist's size is within a fixed small range, then this is a great solution.
var duplicateDetected = false
if(arrList.size > 1){
for(i in 0 until arrList.size){
for(j in 0 until arrList.size){
if(i != j && arrList.get(i) == arrList.get(j)){
duplicateDetected = true
}
}
}
}
private boolean isDuplicate() {
for (int i = 0; i < arrayList.size(); i++) {
for (int j = i + 1; j < arrayList.size(); j++) {
if (arrayList.get(i).getName().trim().equalsIgnoreCase(arrayList.get(j).getName().trim())) {
return true;
}
}
}
return false;
}
String tempVal = null;
for (int i = 0; i < l.size(); i++) {
tempVal = l.get(i); //take the ith object out of list
while (l.contains(tempVal)) {
l.remove(tempVal); //remove all matching entries
}
l.add(tempVal); //at last add one entry
}
Note: this will have major performance hit though as items are removed from start of the list.
To address this, we have two options. 1) iterate in reverse order and remove elements. 2) Use LinkedList instead of ArrayList. Due to biased questions asked in interviews to remove duplicates from List without using any other collection, above example is the answer. In real world though, if I have to achieve this, I will put elements from List to Set, simple!
/**
* Method to detect presence of duplicates in a generic list.
* Depends on the equals method of the concrete type. make sure to override it as required.
*/
public static <T> boolean hasDuplicates(List<T> list){
int count = list.size();
T t1,t2;
for(int i=0;i<count;i++){
t1 = list.get(i);
for(int j=i+1;j<count;j++){
t2 = list.get(j);
if(t2.equals(t1)){
return true;
}
}
}
return false;
}
An example of a concrete class that has overridden equals() :
public class Reminder{
private long id;
private int hour;
private int minute;
public Reminder(long id, int hour, int minute){
this.id = id;
this.hour = hour;
this.minute = minute;
}
#Override
public boolean equals(Object other){
if(other == null) return false;
if(this.getClass() != other.getClass()) return false;
Reminder otherReminder = (Reminder) other;
if(this.hour != otherReminder.hour) return false;
if(this.minute != otherReminder.minute) return false;
return true;
}
}
ArrayList<String> withDuplicates = new ArrayList<>();
withDuplicates.add("1");
withDuplicates.add("2");
withDuplicates.add("1");
withDuplicates.add("3");
HashSet<String> set = new HashSet<>(withDuplicates);
ArrayList<String> withoutDupicates = new ArrayList<>(set);
ArrayList<String> duplicates = new ArrayList<String>();
Iterator<String> dupIter = withDuplicates.iterator();
while(dupIter.hasNext())
{
String dupWord = dupIter.next();
if(withDuplicates.contains(dupWord))
{
duplicates.add(dupWord);
}else{
withoutDupicates.add(dupWord);
}
}
System.out.println(duplicates);
System.out.println(withoutDupicates);
A simple solution for learners.
//Method to find the duplicates.
public static List<Integer> findDublicate(List<Integer> numList){
List<Integer> dupLst = new ArrayList<Integer>();
//Compare one number against all the other number except the self.
for(int i =0;i<numList.size();i++) {
for(int j=0 ; j<numList.size();j++) {
if(i!=j && numList.get(i)==numList.get(j)) {
boolean isNumExist = false;
//The below for loop is used for avoid the duplicate again in the result list
for(Integer aNum: dupLst) {
if(aNum==numList.get(i)) {
isNumExist = true;
break;
}
}
if(!isNumExist) {
dupLst.add(numList.get(i));
}
}
}
}
return dupLst;
}