Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
i have a question on how to remove duplicate for multiple Array. Basically what i want to achieve is to compare from 4 Array and if the contain of Array are exactly the same then i want do not want to print out.
The example of contains for each as below shown:
ArrayStudentName ArrayAge ArrayGender ArrayCourse
A 9 Boy IT
B 10 Boy IT
B 9 Boy IT
A 9 Boy IT
A 9 Girl IT
Is that the only way to remove the duplicate with using 4 times of for loops or do i have to merge 4 arrays into 1 array and then use HashMap to remove duplicate before u print out the result.
The result i need is:
ArrayStudentName ArrayAge ArrayGender ArrayCourse
A 9 Boy IT
B 10 Boy IT
B 9 Boy IT
A 9 Girl IT
You should be brave and take the OOP route. Make a class called Student and fold all the values into that class. Then you just need to put them in a Set which, by definition, does not allow duplicates.
You do, however, have to implement equals and hashcode (or Comparable if you choose not to use a HashSet).
enum Gender {
Boy, Girl, Other;
}
enum Course {
IT, CS;
}
class Student {
final String name;
final int age;
final Gender gender;
Course course;
public Student(String name, int age, Gender gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
#Override
public String toString() {
return name + "\t" + age + "\t" + gender + "\t" + course + "\n";
}
#Override
public int hashCode() {
int hash = 5;
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Student other = (Student) obj;
if (!Objects.equals(this.name, other.name)) {
return false;
}
if (this.age != other.age) {
return false;
}
if (this.gender != other.gender) {
return false;
}
return true;
}
}
public void test() {
System.out.println("Hello");
List<Student> students = Arrays.asList(
new Student("A", 9, Gender.Boy),
new Student("B", 10, Gender.Boy),
new Student("B", 9, Gender.Boy),
new Student("A", 9, Gender.Boy),
new Student("A", 9, Gender.Girl)
);
// Fold it into a Set to eliminate duplicates.
Set all = new HashSet();
all.addAll(students);
// Pull back out into a List.
System.out.println("Students:\n" + all);
}
Create a Student Class.
public class Student {
private String name;
private int age;
private String gender;
private String course;
// Implement Getters and Setters here.
// Then Override the equals method like this:
#Override
public boolean equals(Object obj) {
Student student = (Student) obj;
if ( this.name.equals( student.getName() ) &&
this.age == student.getAge() &&
this.gender.equals( student.getGender() ) &&
this.course.equals( student.getCourse() )
) {
return true;
}
else {
return false;
}
}
}
Now you can create an array of Student objects and compare them using equlas method.
easy way: use a Set (to get unique entries), an keep order: LinkedHashSet
Then Read each line in a List< String >
and keep them in a LinkedHashSet< List< String> >
This gives something like that (you must loop and scan your datas of course !)
Set<List<String>> sls=new LinkedHashSet<List<String>>();
sls.add(Arrays.asList(new String[]{"A","9","Boy","IT"}));
sls.add(Arrays.asList(new String[]{"B","10","Boy","IT"}));
sls.add(Arrays.asList(new String[]{"B","9","Boy","IT"}));
sls.add(Arrays.asList(new String[]{"A","9","Boy","IT"}));
sls.add(Arrays.asList(new String[]{"A","9","Girl","IT"}));
System.out.println(sls);
Related
I know that both hashcode and equals need to be overriden. I tried below program and was wondering why list is able to search student when set couldn't search student when only equals is overridden:
import java.util.*;
class Student {
private int id;
private String name;
public Student(int id, String name) {
this.name = name;
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof Student))
return false;
if (obj == this)
return true;
return this.getId() == ((Student) obj).getId();
}
}
public class StudentHashcodeEquals {
public static void main(String[] args) {
Student alex1 = new Student(1, "Alex");
Student alex2 = new Student(1, "Alex");
System.out.println("alex1 hashcode = " + alex1.hashCode());
System.out.println("alex2 hashcode = " + alex2.hashCode());
System.out.println("Checking equality between alex1 and alex2 = " + alex1.equals(alex2));
List<Student> studentsLst = new ArrayList <Student>();
studentsLst.add(alex1);
studentsLst.add(alex2);
System.out.println("Arraylist size = " + studentsLst.size());
System.out.println("Arraylist contains Alex = " + studentsLst.contains(new Student(1, "Alex")));
HashSet <Student> students = new HashSet <Student>();
students.add(alex1);
students.add(alex2);
System.out.println("HashSet size = " + students.size());
System.out.println("HashSet contains Alex = " + students.contains(new Student(1, "Alex")));
}
}
/*
alex1 hashcode = 366712642
alex2 hashcode = 1829164700
Checking equality between alex1 and alex2 = true
Arraylist size = 2
Arraylist contains Alex = true
HashSet size = 2
HashSet contains Alex = false
*/
When student was inserted into list, I'm assuming that it would insert it into 2 different buckets as the hashcode implementation is not prsent and default object hashcode would get kicked in and it'll store them into 2 different hash codes and when searching for another object, it has to first locate the bucket via hash code but hash code implementation is not there, then how list is able to still identify it whereas set does not??
Thanks!
Lists do not use the hashcode of an object. Depending on their type, they store an array of references to the objects.
If you call contains on a list, it will iterate through the list using .equals() to check if the object is in the list.
I am creating an ArrayList of Accounts (an object) and the Account constructor is
public Account(String name, int accNum, int balance)
{
myName = name;
myAccountNum = accNum;
myBalance = balance;
}
I want to know how to check the ArrayList to determine if a given accountNumber exists in it, and if it does, return true
private static ArrayList<Account> accounts = new ArrayList<Account>();
My initial thought was this, but I do not think that this works
if(accounts.contains(tempAccNum))
{
//executes code that I have
}
For the Java ArrayList, contains performs an object equality comparison. To use .contains, you would need to
Implement the .equals() method for the Account class, and have it check only the this.myAccountNum property against the account number of the input Account.
Create a dummy Account with the desired account number to pass into contains.
A better method would involve evaluating an iterator, and checking the account numbers at each step. Here I assume that myAccountNum is a public property of the Account class.
Iterator<E> it = Accounts.iterator();
while (it.hasNext()) {
Account acc = it.next();
if(acc.myAccountNum == tempAccNum)
return true;
}
For ArrayList specifically, using .get with an index is not too bad:
for(int index = 0; index < Accounts.size(); ++index) {
if(Accounts.get(index).myAccountNum == tempAccNum)
return true;
For other List types, using indices can be very poor.
Ways to iterate over a list in Java
I will suggest you to make it simple by just implementing an equals() method for account class.
#Override
public boolean equals(Object o){
if(o==null)return false;
if(o.getClass()!=this.getClass())return false;
Account demo = (Account)o;
if(!demo.myName.equals(this.myName))return false;
if(demo.myAccountNum != this.myAccountNum)return false ;
if(demo.myBalance = this.myBalance)return false ;
}
then use contains method
First add getter for accNum in Account model
Then try this
public boolean containsAcc(int accno) {
for(int i=0;i<accounts.size();i++) {
if(accounts!= null && accounts.get(i).getMyAccountNum()==acno) {
return true;
}
}
return false;
}
Here getMyAccountNum() is the getter declared in Account model(shown below)
Then check this
if(containsAcc(tempAccNum))
{
//your code
}
Your Account model should be like this
public class Account {
String myName;
int myAccountNum;
int myBalance;
public Account(String name, int accNum, int balance)
{
this.myName = name;
this.myAccountNum = accNum;
this.myBalance = balance;
}
public int getMyAccountNum() {
return myAccountNum;
}
}
I have written an employee class which has a display method and the constructor.
public class employee {
public int empid;
public String name;
public employee(int id, String name){
empid = id;
this.name = name;
}
public void display (){
System.out.println("Employee id: " +empid +"\nEmployee name: "+name);
}
}
I then created three objects of employee and stored them in an array in the main class. I created an if block which will check user guess and print the employee details if he exists or will throw an exception if the data is not present. The if block was enclosed in an enhanced for loop which loops through the array.
public static void main(String[] args) {
// TODO code application logic here
employee priya = new employee (001, "Priya");
employee tamizh = new employee (002, "Tamizh");
employee hari = new employee (003, "hari");
employee[] list = new employee[3];
list[0] = priya;
list[1] = tamizh;
list[2] = hari;
int userGuess = 002;
for (employee l : list){
if (userGuess == l.empid)
{
l.display();
break;
}
else
{
throw new InputMismatchException ("employee doesnot exist");
}
}
}
}
The trouble is that the program throws the exception even if the guess is correct. I tried the int variable empid and then the String variable name, but both the == and .equals didn't work. I searched stackoverflow and the solution suggested was to override the hashcode and equals method in the employee class. I did that.
public class employee {
public int empid;
public String name;
public employee(int id, String name){
empid = id;
this.name = name;
}
public void display (){
System.out.println("Employee id: " +empid +"\nEmployee name: "+name);
}
#Override
public int hashCode(){
final int prime = 31;
int result = 1;
result = prime * result + empid;
result = prime * result + 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 (this.empid != other.empid)
return false;
if (this.name.equals(other.name))
return false;
return true;
}
}
Now when I give the input as 001, the code works fine. But for any other input (including the existing empids 002 and 003), the exception is being thrown.
What had I done wrong in the overriding? Also I don't understand the code I had written to override the two methods. Can someone explain the logic and where I went wrong? Thanks.
Edit: Thanks guys. I have realized my mistake in the for loop and I have edited it. It works perfectly now.
int userGuess = 002;
boolean found = false;
for (employee l : list){
if (userGuess == l.empid)
{
l.display();
found = true;
break;
}
}
if(found == false){
try{
throw new InputMismatchException ("employee doesnot exist");
}
catch(InputMismatchException e){
System.out.println("Employee doesnot exist.");
}
}
Thanks a lot guys. Can someone explain what I have done in equals and hashcode methods? I copied the code from an answer and I couldn't find an explanation for it. Thanks again.
You iterate through your whole array starting at the first entry.
So if you compare the first entry with your user input (lets say its 002) the statement will be false. So it will throw an exception.
To solve this issue you would have to check if an entry has been found AFTER iterating through your array.
int userGuess = 002;
boolean userFound = false;
for (employee l : list)
{
if (userGuess == l.empid)
{
userFound = true;
l.display();
break;
}
}
if(!userFound)
{
throw new InputMismatchException ("employee doesnot exist");
}
To answer your second question:
i dont think you'll need the equals() and hashCode() method.
The equals checks if two objects are the same (see https://msdn.microsoft.com/de-de/library/bsc2ak47(v=vs.110).aspx)
the hashCode() method generates a "unique" value for an object (see https://msdn.microsoft.com/de-de/library/system.object.gethashcode(v=vs.110).aspx)
This should work for you:
boolean found = false;
for (employee l : list){
if (userGuess == l.empid) {
l.display();
found = true;
break;
}
}
if(!found){
throw new InputMismatchException ("employee doesnot exist");
}
Your existing code will not work because the first in the loop is always 001.
Hi I need any method or explanation on how we can order multiple column values in java.
The output should be similar to the multiple column order output in MySQL.
for clarification please check the below link
http://www.dynamicdrive.com/forums/showthread.php?19797-ORDER-BY-Multiple-Columns
Let's say your object looks like this:
public DataObject {
public String name;
public int age;
public String hairColour;
}
Let's say you want to sort them based on age, then hair colour, then name. You could create a comparator as follows:
public DataObjectComparator extends Comparator<DataObject> {
public int compare(DataObject o1, DataObject o2) {
// if the age is the same
if(o1.age == o2.age) {
// if the hair colour is the same
if(o1.hairColour.compareTo(o2.hairColour) == 0) {
// return the name comparison
return o1.name.compareTo(o2.name);
} else { // else return the hair colour comparison
return o1.hairColour.compareTo(o2.hairColour);
}
} else { // else return the age comparison
return o1 < o2 ? -1 : 1;
}
}
}
You can sort arraylist for multiple properties using below sample comparator.
public class CustomeClass implements Comparator<CustomeObject> {
public int compare(CustomeObject o1, CustomeObject o2) {
int value1 = o1.prop1.compareTo(o2.prop1);
if (value1 == 0) {
int value2 = o1.prop2.compareTo(o2.prop2);
if (value2 == 0) {
return o1.prop3.compareTo(o2.prop3);
} else {
return value2;
}
return value1;
}
}
Basically it continues comparing each successive attribute of your class whenever the compared attributes so far are equal (== 0).
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to sort my objects in descending order using comparator.
class Person {
private int age;
}
Here I want to sort a array of Person objects.
How can I do this?
You can do the descending sort of a user-defined class this way overriding the compare() method,
Collections.sort(unsortedList,new Comparator<Person>() {
#Override
public int compare(Person a, Person b) {
return b.getName().compareTo(a.getName());
}
});
Or by using Collection.reverse() to sort descending as user Prince mentioned in his comment.
And you can do the ascending sort like this,
Collections.sort(unsortedList,new Comparator<Person>() {
#Override
public int compare(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
});
Replace the above code with a Lambda expression(Java 8 onwards) we get concise:
Collections.sort(personList, (Person a, Person b) -> b.getName().compareTo(a.getName()));
As of Java 8, List has sort() method which takes Comparator as parameter(more concise) :
personList.sort((a,b)->b.getName().compareTo(a.getName()));
Here a and b are inferred as Person type by lambda expression.
For whats its worth here is my standard answer. The only thing new here is that is uses the Collections.reverseOrder(). Plus it puts all suggestions into one example:
/*
** Use the Collections API to sort a List for you.
**
** When your class has a "natural" sort order you can implement
** the Comparable interface.
**
** You can use an alternate sort order when you implement
** a Comparator for your class.
*/
import java.util.*;
public class Person implements Comparable<Person>
{
String name;
int age;
public Person(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name + " : " + age;
}
/*
** Implement the natural order for this class
*/
public int compareTo(Person p)
{
return getName().compareTo(p.getName());
}
static class AgeComparator implements Comparator<Person>
{
public int compare(Person p1, Person p2)
{
int age1 = p1.getAge();
int age2 = p2.getAge();
if (age1 == age2)
return 0;
else if (age1 > age2)
return 1;
else
return -1;
}
}
public static void main(String[] args)
{
List<Person> people = new ArrayList<Person>();
people.add( new Person("Homer", 38) );
people.add( new Person("Marge", 35) );
people.add( new Person("Bart", 15) );
people.add( new Person("Lisa", 13) );
// Sort by natural order
Collections.sort(people);
System.out.println("Sort by Natural order");
System.out.println("\t" + people);
// Sort by reverse natural order
Collections.sort(people, Collections.reverseOrder());
System.out.println("Sort by reverse natural order");
System.out.println("\t" + people);
// Use a Comparator to sort by age
Collections.sort(people, new Person.AgeComparator());
System.out.println("Sort using Age Comparator");
System.out.println("\t" + people);
// Use a Comparator to sort by descending age
Collections.sort(people,
Collections.reverseOrder(new Person.AgeComparator()));
System.out.println("Sort using Reverse Age Comparator");
System.out.println("\t" + people);
}
}
I would create a comparator for the person class that can be parametrized with a certain sorting behaviour. Here I can set the sorting order but it can be modified to allow sorting for other person attributes as well.
public class PersonComparator implements Comparator<Person> {
public enum SortOrder {ASCENDING, DESCENDING}
private SortOrder sortOrder;
public PersonComparator(SortOrder sortOrder) {
this.sortOrder = sortOrder;
}
#Override
public int compare(Person person1, Person person2) {
Integer age1 = person1.getAge();
Integer age2 = person2.getAge();
int compare = Math.signum(age1.compareTo(age2));
if (sortOrder == ASCENDING) {
return compare;
} else {
return compare * (-1);
}
}
}
(hope it compiles now, I have no IDE or JDK at hand, coded 'blind')
Edit
Thanks to Thomas, edited the code. I wouldn't say that the usage of Math.signum is good, performant, effective, but I'd like to keep it as a reminder, that the compareTo method can return any integer and multiplying by (-1) will fail if the implementation returns Integer.MIN_INTEGER... And I removed the setter because it's cheap enough to construct a new PersonComparator just when it's needed.
But I keep the boxing because it shows that I rely on an existing Comparable implementation. Could have done something like Comparable<Integer> age1 = new Integer(person1.getAge()); but that looked too ugly. The idea was to show a pattern which could easily be adapted to other Person attributes, like name, birthday as Date and so on.
String[] s = {"a", "x", "y"};
Arrays.sort(s, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
System.out.println(Arrays.toString(s));
-> [y, x, a]
Now you have to implement the Comparator for your Person class.
Something like (for ascending order): compare(Person a, Person b) = a.id < b.id ? -1 : (a.id == b.id) ? 0 : 1 or Integer.valueOf(a.id).compareTo(Integer.valueOf(b.id)).
To minimize confusion you should implement an ascending Comparator and convert it to a descending one with a wrapper (like this) new ReverseComparator<Person>(new PersonComparator()).
Using Google Collections:
class Person {
private int age;
public static Function<Person, Integer> GET_AGE =
new Function<Person, Integer> {
public Integer apply(Person p) { return p.age; }
};
}
public static void main(String[] args) {
ArrayList<Person> people;
// Populate the list...
Collections.sort(people, Ordering.natural().onResultOf(Person.GET_AGE).reverse());
}
package com.test;
import java.util.Arrays;
public class Person implements Comparable {
private int age;
private Person(int age) {
super();
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public int compareTo(Object o) {
Person other = (Person)o;
if (this == other)
return 0;
if (this.age < other.age) return 1;
else if (this.age == other.age) return 0;
else return -1;
}
public static void main(String[] args) {
Person[] arr = new Person[4];
arr[0] = new Person(50);
arr[1] = new Person(20);
arr[2] = new Person(10);
arr[3] = new Person(90);
Arrays.sort(arr);
for (int i=0; i < arr.length; i++ ) {
System.out.println(arr[i].age);
}
}
}
Here is one way of doing it.
The java.util.Collections class has a sort method that takes a list and a custom Comparator. You can define your own Comparator to sort your Person object however you like.