I have a class called MyClass:
public class MyClass extends abstractClass implements
someInterface {
Set<VNode> relation_;
Set<VNode> x_;
Set<VNode> y_;
#Override
public boolean equals(Object obj) {
if (!super.equals(obj)) {
return false;
}
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MyClass)) {
return false;
}
MyClass other = (MyClass) obj;
if (relation_ == null) {
if (other.relation_ != null) {
return false;
}
} else if (!relation_.equals(other.relation_)) {
return false;
}
if (x_ == null) {
if (other.x_ != null) {
return false;
}
} else if (!x_.equals(other.x_)) {
return false;
}
if (y_ == null) {
if (other.y_ != null) {
return false;
}
} else if (!y_.equals(other.y_)) {
return false;
}
return true;
}
#Override
public int hashCode() {
int res = new HashCodeBuilder(17, 37).append(relation_).append(x_)
.append(y_).append(getWeight()).toHashCode();
return res;
}
}
The abstract class is as follows:
public abstract class abstractClass {
double weight_;
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof abstractClass)) {
return false;
}
abstractClass other = (abstractClass) obj;
if (Double.doubleToLongBits(weight_) != Double
.doubleToLongBits(other.weight_)) {
return false;
}
return true;
}
public double getWeight() {
return weight_;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(weight_);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
}
Now, if I have HashSet<MyClass> s1 and an MyClass i1, even if s1 has an element s1i whith s1i.equals(i1)=true and s1i.hashCode()=i1.hashCode(), s1.contains(i1) gives me false.
Any explanations?
Other classes:
public class VNode {
Mention mention_;
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof VNode)) {
return false;
}
VNode other = (VNode) obj;
if (mention_ == null) {
if (other.mention_ != null) {
return false;
}
} else if (!mention_.equals(other.mention_)) {
return false;
}
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((mention_ == null) ? 0 : mention_.hashCode());
return result;
}
}
public class Mention extends Range {
private final int id_;
public Mention(final int start, final int end) {
super(start, end);
id_ = getNextMentionID();
}
}
public class Range {
private final int start_;
private final int end_;
/**
* Contr.
*
* #param start
* #param end
*/
public Range(final int start, final int end) {
start_ = start;
end_ = end;
}
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Range)) {
return false;
}
Range other = (Range) obj;
if (end_ != other.end_) {
return false;
}
if (start_ != other.start_) {
return false;
}
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + end_;
result = prime * result + start_;
return result;
}
}
Your equals() method is not readable at all. Since you are using HashCodeBuilder in hashCode(), why not use EqualsBuilder as well?
Version a)
public boolean equals(Object obj){
if(obj == null || obj.getClass()!=getClass()){
return false;
}
MyClass other = (MyClass) obj;
return new EqualsBuilder()
// check parent properties first
.append(this.getWeight(), other.getWeight())
.append(this.relation_, other.relation_)
.append(this.x_, other.x_)
.append(this.y_, other.y_)
.isEquals();
}
Version b)
public boolean equals(Object obj){
// delegate to parent equals first
if(!super.equals(obj)){
return false;
}
MyClass other = (MyClass) obj;
return new EqualsBuilder()
.append(this.relation_, other.relation_)
.append(this.x_, other.x_)
.append(this.y_, other.y_)
.isEquals();
}
Each class should only be concerned with its own variables when calculating equals and hashcode. So, in your MyClass instead of calling getWeight() you should be using the hashcode of the super class. Like you are with equals()!. In this case the effect will be the same.
public int hashCode() {
int res = new HashCodeBuilder(super.hashcode(), 37).append(relation_).append(x_)
.append(y_);
return res;
}
This means any changes to the base class that may affect equals and hashcode are confined to the class and you don't have to update the sub classes.
(Not really an answer, more an observation but its too big for a comment)
Related
Class:
public class Variant
{
private String variant;
private String quantity;
//getters and setters
}
ArrayList:
ArrayList<Variant> variantList = getVariantsList();
Now I want to check whether variantList contains a duplicate entry of variant or not? Please note that variant having two entries with different quantity are to be considered as duplicates.
You can simply ovveride your equals method in your Variant class and provide all the rules for equality in that method.
#Override
public boolean equals(Object obj) {
..
Then you can use contains method or just pass it to a Set, that eliminates all your duplicates.
If you want variant having two entries with different quantity also considered as dup, then you can add that condition in your equals.
Override equals(Object obj) method and try to compare the object on variant and quantity.
Try to loop thru the variantList and do check for duplicity using variantList.contains(variant).
There are two things you need to do:
Override the equals() in your Variant class(minimal code below):
Please note that the below code only checks for quantity and not the variant prop. Your IDE might help you to generate the equals() as well.
#Override
public boolean equals(Object object) {
boolean isEqual = (this == object);
if(object instanceof Variant){
Variant variant = (Variant) object;
isEqual = this.quantity.equals(variant.quantity);
}else{
isEqual = false;
}
return isEqual;
}
Check if the List contains the object - which will use the equals() to check if both are equal.
for (Variant variant : variantList) {
if (variantList.contains(variant)) {
//do logic if its present
}
}
Just check one object with other objects of list
Override equals method in Variant class
#Override
public boolean equals(Object obj) {
if (obj != null) {
if (obj instanceof Variant) {
Variant temp = (Variant) obj;
return this.quantity.equals(temp.quantity); //for different quantity
} else {
return false;
}
}
return false;
}
Then check :
for (int i = 0; i < variantList.size(); i++) {
for (int j = 0; j < variantList.size(); j++) {
if (i != j) {
if (iList.get(i).equals(iList.get(j))) {
//logic when duplicate
break;
}
}
}
}
Follow the below guidelines:
Your Class Variant must override the equals method, since you define a duplicate condition based on quality hence in the equals method check for quality attribute value i.e.
public class Variant {
private String variant;
private String quantity;
public Variant(String variant, String quantity) {
this.variant = variant;
this.quantity = quantity;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((quantity == null) ? 0 : quantity.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;
Variant other = (Variant) obj;
if (quantity == null) {
if (other.quantity != null)
return false;
} else if (!quantity.equals(other.quantity))
return false;
return true;
}
}
Create a method which basically checking whether your list contains the duplicate entries(Variant) or not and return true and false accordingly:
private static boolean isListContainsDuplicateEntries(
ArrayList variantList) {
final List setToReturn = new ArrayList();
for (Variant v : variantList) {
if (!setToReturn.contains(v)) {
setToReturn.add(v);
} else {
return true;
}
}
return false;
}
Now, test the functionality:
public static void main(String[] args) {
Variant variant1 = new Variant("1", "100");
Variant variant2 = new Variant("2", "200");
Variant variant3 = new Variant("3", "200");
ArrayList<Variant> variantList = new ArrayList<>();
variantList.add(variant1);
variantList.add(variant2);
variantList.add(variant3);
System.out.println(Variant.isListContainsDuplicateEntries(variantList));
Output: true
You can use contains():
if (variantList.contains(**<some other Variant object>**)){
...
}
You can simply override your equals method in your Variant and try like this
List<Varient> list =getVariantsList();
System.out.println("here list size"+list.size());
Set<Varient> set = new HashSet<Varient>(list);
System.out.println("here"+set.size());
Create a varient Object:
public class Varient {
private String variant;
private String quantity;
public String getVariant() {
return variant;
}
public void setVariant(String variant) {
this.variant = variant;
}
public String getQuantity() {
return quantity;
}
public void setQuantity(String quantity) {
this.quantity = quantity;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Varient)) return false;
Varient varient = (Varient) o;
if (!quantity.equals(varient.quantity)) return false;
if (!variant.equals(varient.variant)) return false;
return true;
}
#Override
public int hashCode() {
int result = variant.hashCode();
result = 31 * result + quantity.hashCode();
return result;
}
}
Here is your main Program;
public class Test {
public static void main (String [] args){
// getVariantsList() here your list
List<Varient> list =getVariantsList();
Set<Varient> set = new LinkedHashSet<Varient>(list);
}
}
public class Variant {
private String variant;
private String quantity;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((variant == null) ? 0 : variant.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;
Variant other = (Variant) obj;
if (variant == null) {
if (other.variant != null)
return false;
} else if (!variant.equals(other.variant))
return false;
return true;
}
public String getVariant() {
return variant;
}
public void setVariant(String variant) {
this.variant = variant;
}
public String getQuantity() {
return quantity;
}
public void setQuantity(String quantity) {
this.quantity = quantity;
}
public static void main(String[] args) {
// HashSet<Variant> set = new HashSet<>();
// LinkedHashSet<Variant> linkedSet = new LinkedHashSet<>(); // stores
// in input order
/*
* You can use treeset to store data in custom order, in this case
* lexicographically
*/
TreeSet<Variant> treeSet = new TreeSet<>(new VariantComparator());
}
}
In my code I have a set of PlacesInfo object ie.,
Set<PlacesInfo> placeId;
In this set I am adding placeId (String). I need to avoid adding duplicates to my HashSet. Here is my override method below. but, still it is adding duplicate elements to my set. So, how to avoid this?
#Override
public int hashCode() {
int hash = 5;
hash = 97 * hash + Objects.hashCode(this.placeId);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return true;
}
if (this.getClass() != obj.getClass()) {
return false;
}
final PlacesInfo other = (PlacesInfo) obj;
if (!Objects.equals(this.placeId, other.placeId)) {
return false;
}
return true;
}
Try Lombok. I have reduced GAgarwal solution to a trivial class.
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
#EqualsAndHashCode(of={"placeId"})
public class PlacesInfo{
#Getter; #Setter;
int placeId;
PlacesInfo(int placeId) {
this.placeId = placeId;
}
}
Lombok is avalaible by Maven. You won't need to include it in the final jar. Only for compiling.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.14.8</version>
<scope>provided</scope>
</dependency>
Try this
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((placeId == null) ? 0 : placeId.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;
PlacesInfo other = (PlacesInfo) obj;
if (placeId == null) {
if (other.placeId != null)
return false;
} else if (!placeId.equals(other.placeId))
return false;
return true;
}
Below code working fine.If you remove equals and hashcode then it will add two elements.
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
class PlacesInfo {
int placeId;
public int getId() {
return placeId;
}
PlacesInfo(int placeId) {
this.placeId = placeId;
}
public void setId(int placeId) {
this.placeId = placeId;
}
#Override
public boolean equals(Object obj) {
if (obj == null)
return true;
if (this.getClass() != obj.getClass())
return false;
final PlacesInfo other = (PlacesInfo) obj;
if (!Objects.equals(this.placeId, other.placeId))
return false;
return true;
}
#Override
public int hashCode() {
int hash = 5;
hash = 97 * hash + Objects.hashCode(this.placeId);
return hash;
}
}
public class Test {
public static void main(String[] args) {
PlacesInfo t1 = new PlacesInfo(1);
PlacesInfo t2 = new PlacesInfo(1);
System.out.println(t1.equals(t2));
Set<PlacesInfo> tempList = new HashSet<PlacesInfo>(2);
tempList.add(t1);
tempList.add(t2);
System.out.println(tempList);
}
}
I have a class X:
public class X implements Cloneable {
private int a;
private int b;
#Override
public X clone() throws CloneNotSupportedException {
return (X) super.clone();
}
}
I want to remember its initial state. Therefore get his clone:
try {
old = new X();
old = x.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
x - an object of class X, a and b installed.
For example i do with old:
old.setA(7)
How do I now compare the old and the new object, find out whether there were changes. I do so but does not work:
//if object is changed
if (!old.equals(x)){
}
How to check the object has changed or not?
Add below code in your X class
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + a;
result = prime * result + b;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
X other = (X) obj;
if (a != other.a)
return false;
if (b != other.b)
return false;
return true;
}
public boolean equals(Object object2) {
return object2 instanceof MyClass && a.equals(((MyClass)object2).a);
}
So, I have this code written in Java:
import java.util.HashSet;
class Interval{
long from;
long to;
public Interval(long from, long to) {
this.from = from;
this.to = to;
}
public boolean equals(Interval other) {
return from == other.from && to == other.to;
}
}
public class Test {
public static void main(String[] args) {
HashSet<Interval> mySet = new HashSet<Interval>();
mySet.add(new Interval(1,2));
mySet.add(new Interval(1,2));
for(Interval in : mySet) {
System.out.println(in.from + " " + in.to);
}
}
}
The problem is that the set doesn't recognize that there is already an interval from 1 to 2. I defined the function equals, but still it doesn't work. I tried implementing the Comparable interface and overloading the compareTo function, but again nothing. Can somebody tell me how can I solve this problem?
Thank you!
You need to override equals from java.lang.Object.
You did not as yours does not accept Object as parameter.
public boolean equals(Object obj) {
if (obj == null)
return false;
else if (this.getClass() != obj.getClass())
return false;
else {
Interval other = (Interval) obj;
return from == other.from && to == other.to;
}
}
For hashCode, you can do this for example.
public int hashCode() {
return new Long(this.from).hashCode();
}
So overall you get this code.
import java.util.HashSet;
class Interval {
long from;
long to;
public Interval(long from, long to) {
this.from = from;
this.to = to;
}
public boolean equals(Object obj) {
if (obj == null)
return false;
else if (this.getClass() != obj.getClass())
return false;
else {
Interval other = (Interval) obj;
return from == other.from && to == other.to;
}
}
public int hashCode() {
return new Long(this.from).hashCode();
}
}
public class Test003 {
public static void main(String[] args) {
HashSet<Interval> mySet = new HashSet<Interval>();
mySet.add(new Interval(1, 2));
mySet.add(new Interval2(1, 2));
for (Interval in : mySet) {
System.out.println(in.from + " " + in.to);
}
}
}
Use equals and hashCode methods like below it will work perfectly alright
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (from ^ from >>> 32);
result = prime * result + (int) (to ^ to >>> 32);
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Interval other = (Interval) obj;
if (from != other.from) {
return false;
}
if (to != other.to) {
return false;
}
return true;
}
I have an array list that contains Quote objects. I want to be able to sort alphabetically by name, by change, and by percent change. How can I sort my arraylist?
package org.stocktwits.model;
import java.io.Serializable;
import java.text.DecimalFormat;
public class Quote implements Serializable {
private static final long serialVersionUID = 1L;
public String symbol;
public String name;
public String change;
public String percentChange;
public String open;
public String daysHigh;
public String daysLow;
public String dividendYield;
public String volume;
public String averageDailyVolume;
public String peRatio;
public String marketCapitalization;
public String yearHigh;
public String yearLow;
public String lastTradePriceOnly;
public DecimalFormat df = new DecimalFormat("#,###,###,###,###,##0.00");
public DecimalFormat vf = new DecimalFormat("#,###,###,###,###,##0");
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getChange() {
return change;
}
public void setChange(String change) {
if(change.equals("null")){
this.change = "N/A";
}
else{
float floatedChange = Float.valueOf(change);
this.change = (df.format(floatedChange));
}
}
public String getPercentChange() {
return percentChange;
}
public void setPercentChange(String percentChange) {
if(percentChange.equals("null"))
percentChange = "N/A";
else
this.percentChange = percentChange;
}
public String getOpen() {
return open;
}
public void setOpen(String open) {
if(open.equals("null"))
this.open = "N/A";
else
this.open = open;
}
public String getDaysHigh() {
return daysHigh;
}
public void setDaysHigh(String daysHigh) {
if(daysHigh.equals("null"))
this.daysHigh = "N/A";
else{
float floatedDaysHigh = Float.valueOf(daysHigh);
this.daysHigh = (df.format(floatedDaysHigh));
}
}
public String getDaysLow() {
return daysLow;
}
public void setDaysLow(String daysLow) {
if(daysLow.equals("null"))
this.daysLow = "N/A";
else{
float floatedDaysLow = Float.valueOf(daysLow);
this.daysLow = (df.format(floatedDaysLow));
}
}
public String getVolume() {
return volume;
}
public void setVolume(String volume) {
if(volume.equals("null")){
this.volume = "N/A";
}
else{
float floatedVolume = Float.valueOf(volume);
this.volume = (vf.format(floatedVolume));
}
}
public String getDividendYield() {
return dividendYield;
}
public void setDividendYield(String dividendYield) {
if(dividendYield.equals("null"))
this.dividendYield = "N/A";
else
this.dividendYield = dividendYield;
}
public String getAverageDailyVolume() {
return averageDailyVolume;
}
public void setAverageDailyVolume(String averageDailyVolume) {
if(averageDailyVolume.equals("null")){
this.averageDailyVolume = "N/A";
}
else{
float floatedAverageDailyVolume = Float.valueOf(averageDailyVolume);
this.averageDailyVolume = (vf.format(floatedAverageDailyVolume));
}
}
public String getPeRatio() {
return peRatio;
}
public void setPeRatio(String peRatio) {
if(peRatio.equals("null"))
this.peRatio = "N/A";
else
this.peRatio = peRatio;
}
public String getMarketCapitalization() {
return marketCapitalization;
}
public void setMarketCapitalization(String marketCapitalization) {
if(marketCapitalization.equals("null"))
this.marketCapitalization = "N/A";
else
this.marketCapitalization = marketCapitalization;
}
public String getYearHigh() {
return yearHigh;
}
public void setYearHigh(String yearHigh) {
if(yearHigh.equals("null"))
this.yearHigh = "N/A";
else
this.yearHigh = yearHigh;
}
public String getYearLow() {
return yearLow;
}
public void setYearLow(String yearLow) {
if(yearLow.equals("null"))
this.yearLow = "N/A";
else
this.yearLow = yearLow;
}
public String getLastTradePriceOnly() {
return lastTradePriceOnly;
}
public void setLastTradePriceOnly(String lastTradePriceOnly) {
if(lastTradePriceOnly.equals("null")){
this.lastTradePriceOnly = "N/A";
}
else{
float floatedLastTradePriceOnly = Float.valueOf(lastTradePriceOnly);
this.lastTradePriceOnly = (df.format(floatedLastTradePriceOnly));
}
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((change == null) ? 0 : change.hashCode());
result = prime * result
+ ((daysHigh == null) ? 0 : daysHigh.hashCode());
result = prime * result + ((daysLow == null) ? 0 : daysLow.hashCode());
result = prime
* result
+ ((lastTradePriceOnly == null) ? 0 : lastTradePriceOnly
.hashCode());
result = prime
* result
+ ((marketCapitalization == null) ? 0 : marketCapitalization
.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((open == null) ? 0 : open.hashCode());
result = prime * result + ((peRatio == null) ? 0 : peRatio.hashCode());
result = prime * result
+ ((percentChange == null) ? 0 : percentChange.hashCode());
result = prime * result + ((symbol == null) ? 0 : symbol.hashCode());
result = prime * result + ((volume == null) ? 0 : volume.hashCode());
result = prime * result
+ ((yearHigh == null) ? 0 : yearHigh.hashCode());
result = prime * result + ((yearLow == null) ? 0 : yearLow.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;
Quote other = (Quote) obj;
if (change == null) {
if (other.change != null)
return false;
} else if (!change.equals(other.change))
return false;
if (daysHigh == null) {
if (other.daysHigh != null)
return false;
} else if (!daysHigh.equals(other.daysHigh))
return false;
if (daysLow == null) {
if (other.daysLow != null)
return false;
} else if (!daysLow.equals(other.daysLow))
return false;
if (lastTradePriceOnly == null) {
if (other.lastTradePriceOnly != null)
return false;
} else if (!lastTradePriceOnly.equals(other.lastTradePriceOnly))
return false;
if (marketCapitalization == null) {
if (other.marketCapitalization != null)
return false;
} else if (!marketCapitalization.equals(other.marketCapitalization))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (open == null) {
if (other.open != null)
return false;
} else if (!open.equals(other.open))
return false;
if (peRatio == null) {
if (other.peRatio != null)
return false;
} else if (!peRatio.equals(other.peRatio))
return false;
if (percentChange == null) {
if (other.percentChange != null)
return false;
} else if (!percentChange.equals(other.percentChange))
return false;
if (symbol == null) {
if (other.symbol != null)
return false;
} else if (!symbol.equals(other.symbol))
return false;
if (volume == null) {
if (other.volume != null)
return false;
} else if (!volume.equals(other.volume))
return false;
if (yearHigh == null) {
if (other.yearHigh != null)
return false;
} else if (!yearHigh.equals(other.yearHigh))
return false;
if (yearLow == null) {
if (other.yearLow != null)
return false;
} else if (!yearLow.equals(other.yearLow))
return false;
return true;
}
}
If you (almost) always want to use that order you can add the Comparable interface to Quote and implement a compareTo method.
public int compareTo(Quote quote) {
int result = this.getName().compareTo(quote.getName());
if (result == 0) {
result = this.getChange().compareTo(quote.getChange());
}
if (result == 0) {
result = this.getPercentChange().compareTo(quote.getPercentChange());
}
return result;
}
Then use a sorted collection, or sort a list, and the quotes will be sorted.
For ad hoc sorting, a separate, possibly anonymous, Comparator is better.
Everybody is right that you want to use Comparators. Extending on that idea, if you want to be able to sort on multiple criteria, then a class like this will work for you:
public class MultiComparator<T> implements Comparator<T> {
private List<Comparator<T>> comparators;
public MultiComparator(List<Comparator<T>> comparators) {
this.comparators = comparators;
}
public int compare(T o1, T o2) {
for (Comparator<T> comparator : comparators) {
int comparison = comparator.compare(o1, o2);
if (comparison != 0) return comparison;
}
return 0;
}
}
Then you just write really simple comparators for whichever fields you desire and you can combine them into more complex comparators more easily and with more reuse.
Have a look at the ComparatorChain from the Apache Commons Collection. This should do the job. Don't implement logic if is already available and tested.
At the following site I have a tutorial: Sorting Objects By Multiple Attributes"
Create an appropiate Comparator that will compare two items according to your desired criteria. Then use Collections.sort() on your ArrayList.
If at a later time you want to sort by different criteria, call Collections.sort() again with a different Comparator.
Sun has devoted big part of its tutorial to sorting in Java collections:
http://download.oracle.com/javase/tutorial/collections/interfaces/order.html
It discusses both Comparable and Comparator interfaces with examples.
See Collections.sort with an explicit Comparator (or the Collections.sort kind that requires the input to implement Comparable, if you prefer).
There are two things:
Sorting on multiple fields of an object
Multilevel sorting (Here sorting done on first field and then next sorting applied on grouping done on similar items in previous sort)
For #2: I found this below article very much close to what i desire
http://strangeoptics.blogspot.com/2011/09/sorting-objects-by-multiple-attributes.html