Sorting and filtering design question
Hi All,
I have several list of POJO classes like;
publicclass Person
{
private String name;
private String surname;
privateint no=0;
public String getName()
{
return name;
}
publicvoid setName(String name)
{
this.name = name;
}
publicint getNo()
{
return no;
}
publicvoid setNo(int no)
{
this.no = no;
}
public String getSurname()
{
return surname;
}
publicvoid setSurname(String surname)
{
this.surname = surname;
}
}
I would like to sort these classes depending on stituation like sort by Name, or By Surname or By No
Besides, I would like remove some of the object from the list depending on their values for example; if name.equals("xxxx") -->remove it from the list
As I mentioned I have many classes and their fields are changing quite often. I am willing to implement this in good design so that I dont have to change a lot allthe time. I am thinking that I can use decorator and strategy patterns, but I couldnt figure it out.
Thanks in advance
[2202 byte] By [
oturcoa] at [2007-10-2 16:21:32]

Some more information about the problem;The criterias change very often too and I dont want to use a lots of 'if' clauses inside compareTo(Object o) function....
> Hi All,
>
> I have several list of POJO classes like;
> > public class Person
> {
>
> private String name;
> private String surname;
> private int no=0;
>
> public String getName()
> {
> return name;
> }
>
> public void setName(String name)
> {
> this.name = name;
> }
>
> public int getNo()
> {
> return no;
> }
>
> public void setNo(int no)
> {
> this.no = no;
> }
>
> public String getSurname()
> {
> return surname;
> }
>
> public void setSurname(String surname)
> {
> this.surname = surname;
> }
> }
>
>
> I would like to sort these classes depending on
> stituation like sort by Name, or By Surname or By No
> Besides, I would like remove some of the object from
> the list depending on their values for example; if
> name.equals("xxxx") -->remove it from the list
>
> As I mentioned I have many classes and their fields
> are changing quite often. I am willing to
> implement this in good design so that I dont have to
> change a lot allthe time. I am thinking that I can
> use decorator and strategy patterns, but I couldnt
> figure it out.
>
> Thanks in advance
implemet comparable, and override the equals and probablly hashcode methods. you are done.
> > implemet comparable, and override the equals and> probablly hashcode methods. you are done.And how does one implement that interface and thus provide a way to sort by Name for a class, and then using exactly the same class it allows one to sort by
>
> I would like to sort these classes depending on
> stituation like sort by Name, or By Surname or By No
> Besides, I would like remove some of the object from
> the list depending on their values for example; if
> name.equals("xxxx") -->remove it from the list
>
> As I mentioned I have many classes and their fields
> are changing quite often. I am willing to
> implement this in good design so that I dont have to
> change a lot allthe time. I am thinking that I can
> use decorator and strategy patterns, but I couldnt
> figure it out.
1. Just write the code. Update it as the field changes.
2. Generate the code. Build a parser that parses the POJO files and creates a class(es) that provide the required functionality for each attribute in the POJO.
3. Use reflection to dynamically parse the POJOs at runtime and provide the required functionality.
IMHO, 2 is the best. It provides compile time validation with ease of use. Code generation is not necessarily easy to produce initially however.
3 requires the least amount of code. It also means that errors that would normally show up at compile time will only show up at runtime. It is also harder to determine where errors are occurring.
> IMHO, 2 is the best.
implement comparable interface to your person class, which will make you to implement the compare method, where iyou can specify if to sort by first name o r last name. then you can use the collections.sort() method to do the sorting.
this is the easiest way of doing sorting.
also override the equals() method in your class in any way desired so that the equals method will return if one instance is equal to any other ones, and this will allow you to remove or add instances to a vector, for example: vector.add(obj) or vector.remove(obj).
this is the easiest way of doing sorting.
> 3 requires the least amount of code. It also means
> that errors that would normally show up at compile
> time will only show up at runtime. It is also harder
> to determine where errors are occurring.
what you are suggesting is none oo approaches, something that anyone who loves oo programming should not follow.
this will allow you to do vector.remove(obj) should there is an object in the vector that equals obj. add it to your person class:
public boolean equals(Object obj)
{
if (this == obj)
return true;
if ( !(obj instanceof Person) )
return false;
final Person p = (Person)obj;
if ( !p.getFirstName().equals(this.getFirstName()) )
return false;
............
return true;
}
> 1. Just write the code. Update it as the field
> changes.
> 2. Generate the code. Build a parser that parses the
> POJO files and creates a class(es) that provide the
> required functionality for each attribute in the
> POJO.
> 3. Use reflection to dynamically parse the POJOs at
> runtime and provide the required functionality.
>
> IMHO, 2 is the best. It provides compile time
> validation with ease of use. Code generation is not
> necessarily easy to produce initially however.
>
> 3 requires the least amount of code. It also means
> that errors that would normally show up at compile
> time will only show up at runtime. It is also harder
> to determine where errors are occurring.
What about using Strategy where each concrete strategy is a different Comparable that sorts on a given field. As they add fields in the future they could add new Comparables to sort those fields. Not sure how this would be best implemented though.
Sorry I meant Comparator not Comparable.
I dont want use any reflection and dynamic code creation, I prefer to use OO approuch like using strategy design.
But can anyone show me the way to implement a startegy pattern for the person sorting problem;
I can write 3 classes (because I have 3 fields to sort) that implement an interface and ....? I need the help here I guess, I have ideas but I want to know the best.
Cheerss
If you want it to work in the general case--where the possible sort fields are not fixed at compile time, then you'll have to use reflection or code generation.
If the set of possible sort fields is fixed at compile time, you can create code to do it without reflection or code gen, but that code can very quickly grow to be unwieldy.
jverda at 2007-7-13 17:17:12 >

> > IMHO, 2 is the best.
>
> implement comparable interface to your person class,
> which will make you to implement the compare method,
> where iyou can specify if to sort by first name o r
> last name. then you can use the collections.sort()
> method to do the sorting.
>
> this is the easiest way of doing sorting.
>
> also override the equals() method in your class in
> any way desired so that the equals method will return
> if one instance is equal to any other ones, and this
> will allow you to remove or add instances to a
> vector, for example: vector.add(obj) or
> vector.remove(obj).
>
> this is the easiest way of doing sorting.
But it has nothing to do with what the OP requested.
The OP does not want to sort on the the same fields every single time.
>
> > 3 requires the least amount of code. It also means
> > that errors that would normally show up at compile
> > time will only show up at runtime. It is also harder
> > to determine where errors are occurring.
>
> what you are suggesting is none oo approaches,
> something that anyone who loves oo programming should
> not follow.
As usual you have no idea what you are talking about.
> > this is the easiest way of doing sorting.
> The OP does not want to sort on the the same
> fields every single time.
you can do just a bit more work using a comparable object to do dynamix sorting, meaning choosing what to sort by at runtime. look into the same comparable interface. again, this is the ezest way of doing what op wants to do.
class Person immplements Comparable
{
...
compareTo()
{
implement this method for the sorting
}
}
to do dynamic sorting, create a Comparator, and pass it into the method.
"A comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections.sort) to allow precise control over the sort order. Comparators can also be used to control the order of certain data structures (such as TreeSet or TreeMap)."
implement the following, using the code i already posted, and you would then be able to use collection to do the sorting, and you would be able to add or remove from things like vectors, and i think this is what you want to do.
public class Person implements Comparable, Comparator
{
/**
*
*/
public Person()
{
super();
// TODO Auto-generated constructor stub
}
/* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(Object o)
{
// to do fixed sorting
return 0;
}
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object o1, Object o2)
{
// to do dynamic sorting
return 0;
}
public static void main(String[] args)
{
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj)
{
//fill this up with the code i posted
return super.equals(obj);
}
}
@OP: Ignore daFei. He has no idea what he's talking about. He has a well-earned reputation as a buffoon on this site.Comparable is NOT the way to go for selecting different fields to sort on at runtime.
jverda at 2007-7-20 22:52:40 >

And do NOT have your class implement Comparator. That's horrible design. A Comparator should exist separately from the class it compares.
jverda at 2007-7-20 22:52:40 >

> you can do just a bit more work using a comparable
> object to do dynamix sorting, meaning choosing what
> to sort by at runtime. look into the same comparable
> interface. again, this is the ezest way of doing what
> op wants to do.
This is true but hardly an OO approach. The Person object shouldn't care how it's sorted, that's something for the client to decide. Plus, everytime you want to be able to sort in a different way you have to modify Person. At least using Comparator's would allow a new Comparator to be created at any time without modifying the Person object and allow the client to select which to use. I think it's how the client would choose the Comparator that is troubling.
> @OP: Ignore daFei. He has no idea what he's talking> about. He has a well-earned reputation as a buffoon> on this site.> > Comparable is NOT the way to go for selecting> different fields to sort on at runtime.Agreed.
> > @OP: Ignore daFei. He has no idea what he's
> talking
> > about. He has a well-earned reputation as a
> buffoon
> > on this site.
> >
> > Comparable is NOT the way to go for selecting
> > different fields to sort on at runtime.
>
> Agreed.
Ya gotta love how skillfully (NOT) he uses code to demonstrate what he's talking about
--
You can use the toString method to implement SNMP, like this:
public String toString() {
// implement SNMP here
}
-
More evidence that he's never actually written any real, working production code.
jverda at 2007-7-20 22:52:40 >

> And do NOT have your class implement Comparator.
> That's horrible design. A Comparator should exist
> separately from the class it compares.
Agreed. I think using Comparator and the Strategy pattern is what they're after, they're just unsure of how to implement it. To be honest, I am as well and would be interested to see what a good way of doing it is.
I wonder if you couldn't do something like
public abstract class PersonComparator implements Comparator<Person> {
public enum SortBy {
LAST_NAME {
Comparator<Person> getComparator() {
return LastNameComparator.getInstance();
};
private Comparator<Person> getComparator() {}
}
PersonComparator() {
super();
}
public static Comparator<Person> getComparatorFor(SortBy sorting) {
return sorting.getComparator();
}
}
class LastNameComparator extends PersonComparator {...}
Not particularly elegant though, but at least then all you'd have to do is add a SortBy and appropriate PersonComparator implementation when you add fields to Person and want to be able to sort by them, or want to add a different sorting.
I can start a new Thread without using Thread.start() btw:// implement starting new thread without Thread.start() here
package comparable;
public class Date2 implements Comparable {
public int day;
public int month;
public int year;
public int time;
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public int compareTo(Object ob) throws ClassCastException{
if(!(ob instanceof Date2))
throw new ClassCastException("A Date object expected");
int obYear=((Date2) ob).getYear();
return this.year - obYear;
}
}
package comparable;
import java.util.Arrays;
import java.util.ArrayList;
public class Test2{
public static void main(String[] args) {
Date2 obj[]= new Date2[10];
obj[0]=new Date2();
obj[0].setDay(1);
obj[0].setMonth(6);
obj[0].setYear(1998);
obj[0].setTime(1);
obj[1]=new Date2();
obj[1].setDay(3);
obj[1].setMonth(3);
obj[1].setYear(1998);
obj[1].setTime(6);
obj[2]=new Date2();
obj[2].setDay(7);
obj[2].setMonth(9);
obj[2].setYear(1990);
obj[2].setTime(8);
obj[3]=new Date2();
obj[3].setDay(6);
obj[3].setMonth(6);
obj[3].setYear(1987);
obj[3].setTime(2);
obj[4]=new Date2();
obj[4].setDay(2);
obj[4].setMonth(6);
obj[4].setYear(1970);
obj[4].setTime(12);
obj[5]=new Date2();
obj[5].setDay(3);
obj[5].setMonth(3);
obj[5].setYear(1993);
obj[5].setTime(3);
obj[6]=new Date2();
obj[6].setDay(4);
obj[6].setMonth(1);
obj[6].setYear(2000);
obj[6].setTime(5);
obj[7]=new Date2();
obj[7].setDay(4);
obj[7].setMonth(1);
obj[7].setYear(1971);
obj[7].setTime(5);
obj[8]=new Date2();
obj[8].setDay(4);
obj[8].setMonth(2);
obj[8].setYear(2002);
obj[8].setTime(4);
obj[9]=new Date2();
obj[9].setDay(4);
obj[9].setMonth(1);
obj[9].setYear(1999);
obj[9].setTime(5);
System.out.println("Natural Order");
for(int i=0;i<10;i++){
Date2 date = obj;
int day=date.getDay();
int month=date.getMonth();
int year=date.getYear();
int time=date.getTime();
System.out.println("Day"+":"+day+" "+"Month"+":"+month+" "+"Year"+":"+year+" "+"Time"+":"+time+"pm");
}
Arrays.sort(obj);
System.out.println();
System.out.println("Sorted by day");
for(int i=0;i<10;i++){
Date2 date = obj;
int day=date.getDay();
int month=date.getMonth();
int year=date.getYear();
int time=date.getTime();
System.out.println("Day"+":"+day+" "+"Month"+":"+month+" "+"Year"+":"+year+" "+"Time"+":"+time+"pm");
}
}
}
Here i want to the date according to year,month,day and time. so please reply me for this message
