Java JUnit Problem with Ambiguous contactService - java

I'm working on a school project and I have the JUnit test almost here but I cannot for the life of me get this to work.
Contact looks like:
public class Contact {
private String contactID;
private String firstName;
private String lastName;
private String phoneNumber;
private String address;
public Contact (String contactID, String firstName, String lastName, String phoneNumber, String address)
{
//ContactTests Tests
//test to see if contact ID is NOT null or above 10 characters
if (contactID == null || contactID.length()>10)
{
throw new IllegalArgumentException("Invalid contact ID");
//not updating because says do not update it
}
//test to see if first name is NOT null or above 10 characters
if (firstName == null || firstName.length()>10)
{
throw new IllegalArgumentException("Invalid first name");
}
if (lastName == null || lastName.length()>10)
{
throw new IllegalArgumentException("Invalid last name");
}
//test to see if phone number is NOT null or not 10 characters
if (phoneNumber == null || phoneNumber.length()>10 || phoneNumber.length()<10)
{
throw new IllegalArgumentException("Invalid phone number");
}
//test to see if address is NOT null or more than 30 characters
if (address == null || address.length()>30)
{
throw new IllegalArgumentException("Invalid address");
}
//apply them
this.contactID = contactID;
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
this.address = address;
}
//return the variables
//used within tests
public String getContactID() {
return contactID;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public String getAddress() {
return address;
}
//for contactService need to create values here to get variables to set into the array
//used for First Name, Last Name, Phone Number, Address
//used within ContactServices
public void setFirstName (String firstName)
{
this.firstName = firstName;
}
public void setLastName (String lastName)
{
this.lastName = lastName;
}
public void setPhoneNumber (String phoneNumber)
{
this.phoneNumber = phoneNumber;
}
public void setAddress (String address)
{
this.address = address;
}
//test if two contacts are the same
//used in contactService and contactServiceTest
//geeksforgeeks.org/overriding-equals-method-in-java/ helped me in this idea of changing equals
//to becoming more complex
/*#Override
public boolean equals(Object test)
{
if (this == test)
{
return true;
}
if ((getClass() != test.getClass()) || (test == null))
{
return false;
}
Contact another = (Contact) test;
if (contactID == null)
{
if (another.contactID != null || (!contactID.equals(another.contactID)))
{
return false;
}
}
if (firstName == null)
{
if (another.firstName != null || (!firstName.equals(another.firstName)))
{
return false;
}
}
if (lastName == null)
{
if (another.lastName != null || (!lastName.equals(another.lastName)))
{
return false;
}
}
if (phoneNumber == null)
{
if (another.phoneNumber != null || (!phoneNumber.equals(another.phoneNumber)))
{
return false;
}
}
if (address == null)
{
if (another.address != null || (!address.equals(another.address)))
{
return false;
}
}
return true;
}*/
}
ContactService and ContactServiceTest look like;
import java.util.ArrayList;
import contact.Contact;
public class ContactService {
//will contain our list of contacts
//list was removed as working solely with array list now
private ArrayList<Contact> contacts;
public ContactService()
{
//beginning call for the array list
contacts = new ArrayList<>();
}
//need to have an add contact, remove contact and update contact feature
//set add contact to have all values
public boolean addContact(Contact contact)
{
boolean contactAlready = false;
//run through all the contacts in the list made
for (Contact contactList:contacts)
{
//test to see if already a contact
//if so make contactAlready true
if (contactList.equals(contact))
{
contactAlready = true;
}
}
//if not a contact add it as one
if (!contactAlready)
{
contacts.add(contact);
//after adding is now true
return true;
}
else
{
//ending false statement
return false;
}
}
//delete needed via contactID
public boolean deleteContact(String contactID)
{
//run through list of contacts
for (Contact contactList:contacts)
{
//if equals to contactID will remove and return
if (contactList.getContactID().equals(contactID))
{
//remove and return true
contacts.remove(contactList);
return true;
}
}
//else fail and return false
return false;
}
//update is trickiest due to needing to make sure still fits parameters
//"" means no change
public boolean updateContact(String contactID, String firstName, String lastName, String phoneNumber, String address)
{
//run through loop again
for (Contact contactList:contacts)
{
//if contactID matches, run through each with making sure not "" and meets requirements
//then return true as it did equal update.
if (contactList.getContactID().equals(contactID))
{
//set each of the values as long as meet's requirements nor empty
if(!firstName.equals("") && !(firstName.length()>10))
{
contactList.setFirstName(firstName);
}
if(!lastName.equals("") && !(lastName.length()>10))
{
contactList.setFirstName(lastName);
}
if(!phoneNumber.equals("") && (phoneNumber.length()==10))
{
contactList.setFirstName(phoneNumber);
}
if(!address.equals("") && !(address.length()>30))
{
contactList.setFirstName(address);
}
//return true as did update
return true;
}
}
//else fail and return false
return false;
}
}
ContactServiceTest
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.*;
import contact.Contact;
import contact.ContactService;
class ContactServiceTest {
//need to test add, delete and update
//templates
/*
* Contact("1413252", "Jane", "Doe", "4444444444", "Sample 24 Drive");
Contact("1309403", "Malleus", "Draconia", "2187123404", "Valley of Thorns");
Contact("9752319", "Vil", "Schoenheit", "9215501793", "Land of Proxynee");
*/
#Test
public void testAdd()
{
ContactService cs = new ContactService();
Contact contact = new Contact("1413252", "Jane", "Doe", "4444444444", "Sample 24 Drive");
assertTrue(cs.addContact(contact));
//assertEquals(true, cs.addContact(contact));
}
}
I would appreciate any help on this as I'm completely lost and I've gotten no help, sorry for the code dump I just wanted you to have a full picture of what's going on if something -or everything- is wrong.

The "ambigous" error is because the compiler cannot determine whether you are trying to invoke the assertTrue method of class org.junit.Assert or the assertTrue method of org.junit.jupiter.api.Assertions.
To fix this, just remove the following statement:
import static org.junit.Assert.*;
Moreover, here are some tips to improve your code:
Remove the comment of the equals method in Contact class, that method is fine. In addition, you can make Contact class implement the interface java.lang.Comparable and implement the method public int compareTo(Object o), which will be based on what you did for equals, but invoking compareTo instead of equals for each instance member of Contact.
If you follow the fist point, in your ContactService you don't need to visit your ArrayList of contact to verify the existance of an element, that is not necessary.
If you don't want to have duplicated elements in your list, Java gives you the possibility to choose another collection, which is made for the purpose (i.e. TreeSet).
Here is a revisited version of your ContactService:
package contact;
import java.util.ArrayList;
public class ContactService {
//will contain our list of contacts
//list was removed as working solely with array list now
private List<Contact> contacts;
public ContactService()
{
//beginning call for the array list
contacts = new ArrayList<>();
}
//need to have an add contact, remove contact and update contact feature
//set add contact to have all values
public boolean addContact(Contact contact)
{
if(!contacts.contains(contact)) {
return contacts.add(contact);
}
return false;
}
//delete needed via contactID
public boolean deleteContact(String contactID)
{
//run through list of contacts
for (Contact contactElement : contacts)
{
//if equals to contactID will remove and return
if (contactElement.getContactID().equals(contactID))
{
return contacts.remove(contactElement);
}
}
//else fail and return false
return false;
}
//update is trickiest due to needing to make sure still fits parameters
//"" means no change
public boolean updateContact(String contactID, String firstName, String lastName, String phoneNumber, String address)
{
//run through loop again
for (Contact contactList:contacts)
{
//if contactID matches, run through each with making sure not "" and meets requirements
//then return true as it did equal update.
if (contactList.getContactID().equals(contactID))
{
//set each of the values as long as meet's requirements nor empty
if(!firstName.equals("") && !(firstName.length()>10))
{
contactList.setFirstName(firstName);
}
if(!lastName.equals("") && !(lastName.length()>10))
{
contactList.setFirstName(lastName);
}
if(!phoneNumber.equals("") && (phoneNumber.length()==10))
{
contactList.setFirstName(phoneNumber);
}
if(!address.equals("") && !(address.length()>30))
{
contactList.setFirstName(address);
}
//return true as did update
return true;
}
}
//else fail and return false
return false;
}
}
In addition, here is another version of ContactServiceTest, where I just added a couple of more scenarios. Starting from this, you can go on and implement more tests, for example related to updateContact.
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import contact.Contact;
import contact.ContactService;
class ContactServiceTest {
//need to test add, delete and update
//templates
/*
* Contact("1413252", "Jane", "Doe", "4444444444", "Sample 24 Drive");
Contact("1309403", "Malleus", "Draconia", "2187123404", "Valley of Thorns");
Contact("9752319", "Vil", "Schoenheit", "9215501793", "Land of Proxynee");
*/
#Test
public void testAdd()
{
ContactService cs = new ContactService();
Contact contact = new Contact("1413252", "Jane", "Doe", "4444444444", "Sample 24 Drive");
assertTrue(cs.addContact(contact));
contact = new Contact("1413252", "Jane", "Doe", "4444444444", "Sample 24 Drive");
//assertEquals(true, cs.addContact(contact));
assertFalse(cs.addContact(contact));
}
#Test
public void testRemove()
{
ContactService cs = new ContactService();
Contact contact = new Contact("1413252", "Jane", "Doe", "4444444444", "Sample 24 Drive");
cs.addContact(contact);
assertTrue(cs.deleteContact("1413252"));
//assertEquals(true, cs.addContact(contact));
}
}

Related

How to get name from a list of employees

I am trying to print "name" of an employee from a list of employees. Below is my pojo class.
import java.time.LocalDate;
public class Employee {
private String name;
private String empID;
private Designation designation;
private LocalDate dateOfJoining;
private int monthlySalary;
public Employee(String name, String empID, Designation designation, LocalDate dateOfJoining, int monthlySalary) {
super();
this.name = name;
this.empID = empID;
this.designation = designation;
this.dateOfJoining = dateOfJoining;
this.monthlySalary = monthlySalary;
}
public Employee() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmpID() {
return empID;
}
public void setEmpID(String empID) {
this.empID = empID;
}
public Designation getDesignation() {
return designation;
}
public void setDesignation(Designation designation) {
this.designation = designation;
}
public LocalDate getDOJ() {
return dateOfJoining;
}
public void setDOJ(LocalDate dOJ) {
dateOfJoining = dOJ;
}
public int getMonthlySalary() {
return monthlySalary;
}
public void setMonthlySalary(int monthlySalary) {
this.monthlySalary = monthlySalary;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dateOfJoining == null) ? 0 : dateOfJoining.hashCode());
result = prime * result + ((designation == null) ? 0 : designation.hashCode());
result = prime * result + ((empID == null) ? 0 : empID.hashCode());
result = prime * result + monthlySalary;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (dateOfJoining == null) {
if (other.dateOfJoining != null)
return false;
} else if (!dateOfJoining.equals(other.dateOfJoining))
return false;
if (designation == null) {
if (other.designation != null)
return false;
} else if (!designation.equals(other.designation))
return false;
if (empID == null) {
if (other.empID != null)
return false;
} else if (!empID.equals(other.empID))
return false;
if (monthlySalary != other.monthlySalary)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
#Override
public String toString() {
return "Employee [name=" + name + ", empID=" + empID + ", designation=" + designation + ", DOJ=" + dateOfJoining
+ ", monthlySalary=" + monthlySalary + "]";
}
}
Now while I am trying to print the "name", I am getting null value.
Please see as below,
import java.time.LocalDate;
import java.time.Period;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Employecomparable {
public static void main(String[] args) {
JoiningDate jd = new JoiningDate();
Employee emp = new Employee();
List<Employee> listofemployee = new ArrayList<>();
listofemployee.add(new Employee("abc", "12345", Designation.ASE,jd.date1 , 20000));
listofemployee.add(new Employee("abcd", "24680", Designation.SE, jd.date2, 30000));
listofemployee.add(new Employee("abcde", "13570", Designation.SSE,jd.date3, 40000));
listofemployee.add(new Employee("abcdef", "13690", Designation.TL, jd.date4, 60000));
listofemployee.add(new Employee("xyz", "10909", Designation.AM, jd.date5, 800000));
listofemployee.add(new Employee("koool", "89076", Designation.M, jd.date6, 2000));
System.out.println("The name of employee is "+emp.getName());
I am getting the output as "null".
In console I get, The name of employee is null.
How do i print the name?
Please help!
To print the name of a particular employee, kindly update the emp object.
emp = listofemployee.get(indexWithinTheList);
System.out.println("The name of employee is "+emp.getName());
Example:
emp = listofemployee.get(0);
System.out.println("The name of employee is "+emp.getName());
Output : The name of employee is abc
You may want to iterate over your employee and then print the name. Reason you get null is you created Employee object with default constructor. Which would mean name being string object would take default null value which is what you see.
If you want to print employee names, you could do the following:
for (Employee employee: listofemployee) {
System.out.println("The name of employee is " + employee.getName());
}
Since you are using List interface, you can access individual object by it's index. E.g. to get first employee name:
System.out.println("The name of employee is " + listofemployee.get(0).getName());
The error you are getting is because you have created the Employee object like below.
Employee emp = new Employee(); After that you are populating the list using new Employee. But you have not set any value to variable emp.so getName from emp will return null. If you want to get the value from emp. You first need to set the name using emp.SetName("Any name"); No you will get the value using emp.getName();
1 - Create Employee object like below:-
Employee emp =new Employee("xyz", "10909", Designation.AM, jd.date5,
800000);
2 - Then store into list.
3 - After that iterate over list and print result as per your requirement.
public static void main(String[] args) {
JoiningDate jd = new JoiningDate();
Employee emp = new Employee();
List<Employee> listofemployee = new ArrayList<>();
emp = new Employee("abc", "12345", Designation.ASE,jd.date1 , 20000);
listofemployee.add(emp);
emp =new Employee("abcd", "24680", Designation.SE, jd.date2, 30000);
listofemployee.add(emp);
emp =new Employee("abcde", "13570", Designation.SSE,jd.date3, 40000);
listofemployee.add(emp);
emp = new Employee("abcdef", "13690", Designation.TL, jd.date4, 60000);
listofemployee.add(emp);
emp =new Employee("koool", "89076", Designation.M, jd.date6, 2000);
listofemployee.add(emp);
emp =new Employee("xyz", "10909", Designation.AM, jd.date5, 800000);
listofemployee.add(emp);
System.out.println("The name of employee is "+emp.getName());
Iterator<Employee> itr = listofemployee.iterator();
// checking the next element availabilty
while (itr.hasNext())
{
System.out.println("name " + (itr.next()).getName());
}
}

common objects in 2 ArrayList

I have 2 ArrayList. And I want elements with common phone.
ArrayList<Contact> phone_contacts;
ArrayList<Contact> registered_users;
I used below method to get common elements:
ArrayList<Contact> common_contacts = new ArrayList<Contact>(phone_contacts);
common_contacts.retainAll(registered_users);
But, the result I get is empty. How can I get common phone contact in common_contacts ArrayList?
Contact
public class Contact {
private String name;
private String phone;
public Contact(String name, String phone) {
this.name = name;
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
First, if you are treating a phone number as an identifier, I would advise caution. Falsehoods Programmers Believe About Phone Numbers
With that said...
retainAll ultimately uses the equals method. Given that you have a custom object (and not something like a String or int that have a defined equals), the simplest method would be to define an equals method for Contact that returns true if the two have the same phone number.
However, that might not be what you are looking for. For example, equals might need to check the name in other contexts.
There are a couple other approaches you could take. Since you mentioned Android, Java 8 streams are currently out. An Iterator loop might do the job. Collect all of the phone numbers for registered users into a Set (so you have the unique list), then start with a List of all of your contacts, and remove any that don't have a phone number from that set.
Set<String> registeredPhoneNumbers = new HashSet<>();
for (Contact c : registered_users) {
registeredPhoneNumbers.add(c.getPhone());
}
List<Contact> common_contacts = new ArrayList<>(phone_contacts);
for (Iterator<Contact> iter = common_contacts.iterator(); iter.hasNext();) {
Contact c = iter.next();
if (!registeredPhoneNumbers.contains(c.getPhone())) {
iter.remove();
}
}
Since you mentioned in comments that there could be a million distinct registered_users, this might be more space-efficient:
Set<String> phoneNumbers = new HashSet<>();
for (Contact c : phone_contacts) {
phoneNumbers.add(c.getPhone());
}
Set<String> overlappingNumbers = new HashSet<>();
for (Contact registered : registered_users) {
if (phoneNumbers.contains(registered.getPhone())) {
overlappingNumbers.add(registered.getPhone());
}
}
List<Contact> common_contacts = new ArrayList<>();
for (Contact contact : phone_contacts) {
if (overlappingNumbers.contains(contact.getPhone())) {
common_contacts.add(contact);
}
}
}
You may want to check the phone number for null as well.
Add these lines to your Contact class:
#Override
public boolean equals(Object obj) {
return obj instanceof Contact &&
this.name != null && this.name.equals(((Contact)obj).name) &&
this.phone!= null && this.phone.equals(((Contact)obj).phone);
}
Ref: https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-
See Also: hashCode()
If you use the method RetainAll in the List the you will get the common objects between 2 Lists..\
Example:
consider the lists of integers, (just for the sake of the example) it will work with your class...
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(0, 1, 2, 3, 4, 5));
List<Integer> list2 = new ArrayList<Integer>(Arrays.asList(1, 3, 5));
List<Integer> list3 = new ArrayList<Integer>(list1);
list3.retainAll(list2);
System.out.println("List1:" + list1);
System.out.println("List2:" + list2);
System.out.println("List common:" + list3);
}
In your case the class contacts needs to be modified so the Method ArrayLst.retainAll() can somehow identify whether a Contact is the same as the other using as criteria the Phone number...
Modify/Improve the Contact Class by adding the HashCode and Equals:
but you need to use as criteria only the phone Number
public class Contact {
private String name;
private int phone;
public Contact(String name, int phone) {
this.name = name;
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "Contact [name=" + name + ", phone=" + phone + "]";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + phone;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Contact other = (Contact) obj;
if (phone != other.phone)
return false;
return true;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
this.phone = phone;
}
}
Implement the List of Contacts and call the method RetainAll
public static void main(String[] args) {
List<Contact> list1 = new ArrayList<Contact>(Arrays.asList(new Contact(UUID.randomUUID().toString(), 1),
new Contact(UUID.randomUUID().toString(), 2), new Contact(UUID.randomUUID().toString(), 3),
new Contact(UUID.randomUUID().toString(), 4), new Contact(UUID.randomUUID().toString(), 5)));
List<Contact> list2 = new ArrayList<Contact>(Arrays.asList(new Contact(UUID.randomUUID().toString(), 1),
new Contact(UUID.randomUUID().toString(), 3), new Contact(UUID.randomUUID().toString(), 5)));
List<Contact> list3 = new ArrayList<Contact>(list1);
list3.retainAll(list2);
System.out.println("List1:" + list1);
System.out.println("List2:" + list2);
System.out.println("List common:" + list3);
}

Java How to search if user input is equal to something in my array

Hello my goal is to get the user to input some customerID value and some videoID how would I check to make sure the user inputs a correct customerID and videoID in my array I have made for these fields and tell the user they have inputted the wrong ID. This is what i have so far for my code
public static void HireVideo(){
System.out.println("Enter Customer ID");
String customerID = sc.next();
System.out.println("Enter Video ID");
String videoID = sc.next();
HireList.add(new Hire(customerID, videoID));
}
in an effort to be as close to your code as possible (i.e. what I assume is a static list wrapper class).
public class HireList {
private static List<Hire> hires = new ArrayList<Hire>();
public static void add(Hire hire) {
hires.add(hire);
}
public static boolean contains(Hire other) {
return hires.contains(other);
}
}
the magic however happens in the Hire class:
public class Hire {
private String customerId;
private String videoId;
public Hire(String customerId, String videoId) {
this.customerId = customerId;
this.videoId = videoId;
}
#Override
public int hashCode() {
int hash = 3;
hash = 67 * hash + Objects.hashCode(this.customerId);
hash = 67 * hash + Objects.hashCode(this.videoId);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
final Hire other = (Hire) obj;
if (!this.customerId.equals(other.customerId)) {
return false;
}
if (!this.videoId.equals(other.videoId)) {
return false;
}
return true;
}
}
List<T>.contains(T other) uses the equals method of T, therefore overriding it will allow us to control the behavior of contains.
test:
public static void main(String[] args) {
HireList.add(new Hire("1", "1"));
HireList.add(new Hire("2", "2"));
System.out.println(HireList.contains(new Hire("2", "2"))); //output: true
}
if contains is all you are concerned with though I would suggest using a HashSet as opposed to a ArrayList.

Compare elements in list and remove if some properties are the same

I have an array list of objects which contains eg:
Name
Address
Phone
Many other properties...
I wish to remove some objects in this list, if some of the properties has the same value as other objects in the array list. I need to loop though the whole list and see if the Name, Address and Phone already exists in this list. I can not do a simple:
for (...)
if (!newlist.contains(element)) { newlist.add(element); }
As I only need to check specific properties are the same before adding the element to a new list.
Can anyone guide me in the right direction?
How about using Set with a custom Comparator ? Have your object class implement Comparable. In the compare method you can then write your test to match the objects exactly how you need it.
Create a Key Class let us say Employee.java with below code.
package com.innovation;
public class Employee {
private String name;
private String address;
private String phone;
public Employee() {
super();
}
public Employee(String name, String address, String phone) {
super();
this.name = name;
this.address = address;
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((phone == null) ? 0 : phone.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (phone == null) {
if (other.phone != null)
return false;
} else if (!phone.equals(other.phone))
return false;
return true;
}
#Override
public String toString() {
return "Employee [name=" + name + ", address=" + address + ", phone="
+ phone + "]";
}
}
Now create a Client class where you want to apply your logic let us assume a class containing main method say Client.java
package com.innovation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Client {
public static void main(String[] args) {
Set<Employee> empSet = new HashSet<Employee>(populateList());
for (Employee employee : empSet)
{
System.out.println(employee);
}
}
public static List<Employee> populateList()
{
List<Employee> lsts = new ArrayList<Employee>();
lsts.add(new Employee("rais","gurgaon","123456"));
lsts.add(new Employee("alam","Delhi","123685"));
lsts.add(new Employee("shyam","Mumbai","1257456"));
lsts.add(new Employee("ramesh","Ahmadabad","196356"));
lsts.add(new Employee("rais","gurgaon","123456"));
lsts.add(new Employee("rais","gurgaon","123456"));
lsts.add(new Employee("rais","gurgaon","123456"));
return lsts;
}
}
You will see below out put. it is clearly visible that duplicate entry present in list is removed in set. it all magic of good implementation of equals and hashcode method.
Employee [name=rais, address=gurgaon, phone=123456]
Employee [name=ramesh, address=Ahmadabad, phone=196356]
Employee [name=alam, address=Delhi, phone=123685]
Employee [name=shyam, address=Mumbai, phone=1257456]

remove duplicate object in Java

I've User object a shown below:
User.java:
public class User {
public String firstName;
public String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Override
public int hashCode() {
return (this.firstName.hashCode() + this.lastName.hashCode());
}
#Override
public boolean equals(Object obj) {
if(obj instanceof User) {
User temp = (User) obj;
if(this.firstName.equals(temp.firstName) && this.lastName.equals(temp.lastName)) {
return true;
}
}
return false;
}
}
And main program is shown below:
import java.util.*;
class pp {
public static void main(String[] args) {
List<User[]> a = new ArrayList<User[]>();
User[] u = new User[3];
u[0] = new User();
u[0].setFirstName("Mike"); u[0].setLastName("Jordon");
u[1] = new User();
u[1].setFirstName("Jack"); u[1].setLastName("Nicolson");
u[2] = new User();
u[2].setFirstName("Jack"); u[2].setLastName("Nicolson");
a.add(u);
Set<User[]> s = new HashSet<User[]>(a);
for (User[] ss : s) {
for (int i=0; i<ss.length; i++) {
System.out.println(ss[i].getFirstName() + " " + ss[i].getLastName());
}
}
}
}
I'm expecting output to be
Mike Jordon
Jack Nicolson
But somehow, its retaining duplicate object & printing as:
Mike Jordon
Jack Nicolson
Jack Nicolson
Can any one tell me what I'm missing??
Thanks!
Your equals method should be like :
#Override
public boolean equals(Object obj) {
if(obj instanceof User) {
User temp = (User) obj;
if(this.firstName.equals(temp.firstName) && this.lastName.equals(temp.lastName)) {
return true;
}
}
return false;
}
I have gone through your questions and understood the requirement. Please find the similar kind of code I have implemented and also successfully removed objects from a collection those having duplicate values.
#Snipet...
Employee.java
==============
package com.hcl;
public class Employee {
public String empid;
public String empname;
public double sal;
public int age;
public Employee(){
}
public Employee(String empid,String empname,double sal,int age){
this.empid = empid;
this.empname = empname;
this.sal = sal;
this.age = age;
}
public String getEmpid() {
return empid;
}
public void setEmpid(String empid) {
this.empid = empid;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/**
* This override method playes a major role to remove duplicate values
*/
#Override
public int hashCode() {
return (this.empid.hashCode() + this.empname.hashCode()+String.valueOf(this.sal).hashCode()+String.valueOf(this.age).hashCode());
}
/**
* This override method plays a major role to remove duplicate values
*/
#Override
public boolean equals(Object obj) {
if(obj instanceof Employee) {
Employee temp = (Employee) obj;
if(this.empid.equals(temp.empid) && this.empname.equals(temp.empname) && String.valueOf(this.sal).equals(String.valueOf(temp.sal)) && String.valueOf(this.age).equals(String.valueOf(temp.age))) {
return true;
}
}
return false;
}
}
#Snipet..........
RemoveDuplicateObjects.java
=============================
package com.hcl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class RemoveDuplicateObjects {
public static void main(String[] args) {
Employee emp1 = new Employee("1","bapi",1000,31);
Employee emp2 = new Employee("2","mano",2000,29);
Employee emp3 = new Employee("1","bapi",1000,31); // emp3 == emp1 duplicate object
Employee emp4 = new Employee("3","Rohan",3000,27);
Employee emp5 = new Employee("1","bapi",1000,31); // emp5 == emp3 == emp1 duplicate object
RemoveDuplicateObjects obj = new RemoveDuplicateObjects();
// empList contains objects having duplicate values. How to remove duplicate?
List<Employee> empList = new ArrayList<Employee>();
empList.add(emp1);
empList.add(emp2);
empList.add(emp3);
empList.add(emp4);
empList.add(emp5);
if(emp1.equals(emp2)){
System.out.println("emp1 and emp2 are equal");
}
if(emp1.equals(emp3)){
System.out.println("emp1 and emp3 are equal");
}
obj.removeDuplicate(empList);
}
// method is used for removing objects having duplicate values
private void removeDuplicate(List<Employee> empList) {
Set<Employee> empSet = new HashSet<Employee>();
empSet.addAll(empList);
for(Employee e: empSet){
System.out.println("id = "+e.getEmpid());
System.out.println("name = "+e.getEmpname());
System.out.println("sal = "+e.getSal());
System.out.println("age = "+e.getAge());
}
}
}
Done! Now you can run the program and analyze the solution.
I suppose you want this:
class pp {
public static void main(String[] args) {
Set<User> a = new HashSet<User>();
User u = new User();
u.setFirstName("Mike"); u.setLastName("Jordon");
a.add(u);
u = new User();
u.setFirstName("Jack"); u.setLastName("Nicolson");
a.add(u);
u = new User();
u.setFirstName("Jack"); u.setLastName("Nicolson");
a.add(u);
for (User ss : a) {
System.out.println(ss.getFirstName() + " " + ss.getLastName());
}
}
}
try this my friend :
Iterator i = a.iterator();
while (i.hasNext()) {
User u = (User) i.next();
boolean match = false;
Iterator j = a.iterator();
boolean once = true;
while (j.hasNext()) {
if(once){j.next();} // to skip own occurence only once
once = false;
User u2 = (User) j.next();
if (u.getFirstName().equals(u2.getFirstName())
&& u.getLastName().equals(u2.getLastName())) {
match = true;
}
}
if (!match) {
// print
}
}
Override the equals method as suggested by Jason.
Now for removing duplicates you need to use Set.
List allows duplicate values so you will always have duplicate values. Set doesnot allow duplicate value so it will solve your problem.
You're using a Set of arrays, where the set has one element, namely an array of three Users. Arrays don't enforce or check uniqueness, which is why you get the same User twice. If you removed the arrays altogether, and simply used a Set, you'd get the "unique" behaviour you want.
First you should use a Set to store objects instead of a array if you dont want duplicates. (Arrays and List do allow duplicate objects to be stores)
Second your equals methods should use String.equal method for comparison and should check for null values too to be on the safe side. I would use the IDE's auto generate feature for hashcode and equals methods always (i.e. Eclipse Source -> Generate hashCode() and equals()...)
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
return true;
}
and main method
public static void main(String[] args) {
List<Set<User>> a = new ArrayList<Set<User>>();
Set<User> set = new HashSet<User>();
User u = new User();
u.setFirstName("Mike"); u.setLastName("Jordon");
set.add(u);
u = new User();
u.setFirstName("Jack"); u.setLastName("Nicolson");
set.add(u);
u = new User();
u.setFirstName("Jack"); u.setLastName("Nicolson");
set.add(u);
a.add(set);
for (Set<User> ss : a) {
for (User user : ss) {
System.out.println(user.getFirstName() + " " + user.getLastName());
}
}
}
In general, you can add elements to a Set to remove duplicates. However, you don't want to add the entire array to the collection in general; you just want to add the individual elements, like so:
public static void main(String[] args) {
Set<User> a = new HashSet<User>();
User[] u = new User[3];
u[0] = new User();
u[0].setFirstName("Mike"); u[0].setLastName("Jordon");
u[1] = new User();
u[1].setFirstName("Jack"); u[1].setLastName("Nicolson");
u[2] = new User();
u[2].setFirstName("Jack"); u[2].setLastName("Nicolson");
// Add each of the users to the Set. Note that there are three.
for (User user : u) {
a.add(u);
}
// Get the results back as an array. Note that this will have two.
User[] duplicatesRemoved = new User[0];
a.toArray(duplicatesRemoved);
}
Hi you can write a method in pp class in order to remove duplicate elements from the user array as follows :
private User[] getUserArrayWithoutDuplicates(User[] a) {
int count = a.length;
Set<User> tempset = new HashSet<User>();
for (int i = 0; i < count; i++) {
User[] user = a;
int arraysize = user.length;
for (int j = 0; j < arraysize; j++)
tempset.add(user[j]);
}
User[] usr = new User[tempset.size()];
Iterator<User> tempIterator = tempset.iterator();
int p = 0;
while (tempIterator.hasNext()) {
User user = tempIterator.next();
usr[p] = new User();
usr[p].setFirstName(user.firstName);
usr[p].setLastName(user.lastName);
p++;
}
return usr;
}
This method will remove the duplicate entries from User array and return the User array without duplicate entries.

Categories