java - Passing Object type and Field to Comparator -


is possible write comparator can pass object type, field type , field sort on? i've made small changes http://www.davekoelle.com/files/alphanumcomparator.java accommodate sorting on field email of type string in object type user . have code works.

public class main {      public static void main(string[] args) {          list<user> users = new arraylist<>();          users.add(new user(7, "user1", "user1@c.com"));         users.add(new user(11, "user20", "user20@c.com"));         users.add(new user(5, "admin20", "admin20@c.com"));         users.add(new user(10, "user11", "user11@c.com"));         users.add(new user(6, "admin21", "admin21@c.com"));         users.add(new user(12, "user21", "user21@c.com"));         users.add(new user(8, "user2", "user2@c.com"));         users.add(new user(1, "admin1", "admin1@c.com"));         users.add(new user(3, "admin10", "admin10@c.com"));         users.add(new user(2, "admin2", "admin2@c.com"));         users.add(new user(9, "user10", "user10@c.com"));         users.add(new user(4, "admin11", "admin11@c.com"));          (user item : users) {             system.out.println(item.getemail());         }          system.out.println("__________________________");          collections.sort(users, new alphanumcomparator());          (user item : users) {             system.out.println(item.getemail());         }     } } 

.

public class user {      int id;     string name;     string email;  // constructor, getters , setters } 

.

public class alphanumcomparator implements comparator<user> {     private final boolean isdigit(char ch) {         return ((ch >= 48) && (ch <= 57));     }      /**      * length of string passed in improved efficiency (only need calculate once)      **/     private final string getchunk(string s, int slength, int marker) {         stringbuilder chunk = new stringbuilder();         char c = s.charat(marker);         chunk.append(c);         marker++;         if (isdigit(c)) {             while (marker < slength) {                 c = s.charat(marker);                 if (!isdigit(c))                     break;                 chunk.append(c);                 marker++;             }         } else {             while (marker < slength) {                 c = s.charat(marker);                 if (isdigit(c))                     break;                 chunk.append(c);                 marker++;             }         }         return chunk.tostring();     }      public int compare(user u1, user u2) {         if ((u1 == null) || (u2 == null)) {             return 0;         }          int thismarker = 0;         int thatmarker = 0;         int s1length = u1.getemail().length();         int s2length = u2.getemail().length();          while (thismarker < s1length && thatmarker < s2length) {             string thischunk = getchunk(u1.getemail(), s1length, thismarker);             thismarker += thischunk.length();              string thatchunk = getchunk(u2.getemail(), s2length, thatmarker);             thatmarker += thatchunk.length();              // if both chunks contain numeric characters, sort them numerically             int result = 0;             if (isdigit(thischunk.charat(0)) && isdigit(thatchunk.charat(0))) {                 // simple chunk comparison length.                 int thischunklength = thischunk.length();                 result = thischunklength - thatchunk.length();                 // if equal, first different number counts                 if (result == 0) {                     (int = 0; < thischunklength; i++) {                         result = thischunk.charat(i) - thatchunk.charat(i);                         if (result != 0) {                             return result;                         }                     }                 }             } else {                 result = thischunk.compareto(thatchunk);             }              if (result != 0)                 return result;         }          return s1length - s2length;     } } 

how can pass object type, field type , field sort on collections.sort(users, new alphanumcomparator()); in main class alphanumcomparator , how can accommodate in alphanumcomparator? in case pass object type user field email , field type string. if sort on id pass object type user, field email , field type int.

i keep alphanumcomparator is, , create new class fieldcomparator:

public class fieldcomparator<t> implements comparator<t> {     private static final logger log = logger.getlogger(             fieldcomparator.class.getname());     private static final alphanumcomparator alphanum = new alphanumcomparator();      private final field field;     private final boolean isstring;     private final boolean iscomparable;      public fieldcomparator(class<t> clazz, string name) {         try {             field = clazz.getdeclaredfield(name);             field.setaccessible(true);             class<?> fieldtype = field.gettype();             isstring = fieldtype == string.class;             iscomparable = comparable.class.isassignablefrom(fieldtype);         } catch (nosuchfieldexception | securityexception ex) {             log.log(level.severe, null, ex);             throw new runtimeexception(ex.getmessage());         }     }      @override     public int compare(t o1, t o2) {         try {             object value1 = field.get(o1);             object value2 = field.get(o2);             if (value1 == null) {                 return value2 == null ? 0 : -1;             } else if (value2 == null) {                 return 1;             } else if (isstring) {                 return alphanum.compare((string)value1, (string)value2);             } else if (iscomparable) {                 return ((comparable)value1).compareto(value2);             } else {                 // don't know how compare fields                 return 0;             }         } catch (illegalargumentexception | illegalaccessexception ex) {             log.log(level.severe, null, ex);             throw new runtimeexception(ex.getmessage());         }     } } 

update:

to deal primitive types, can change 1 line of method compare:

    } else if (iscomparable || value1 instanceof comparable) { 

update 2:

you main method become:

public static void main(string[] args) {      list<user> users = new arraylist<>();      users.add(new user(7, "user1", "user1@c.com"));     users.add(new user(11, "user20", "user20@c.com"));     users.add(new user(5, "admin20", "admin20@c.com"));     users.add(new user(10, "user11", "user11@c.com"));     users.add(new user(6, "admin21", "admin21@c.com"));     users.add(new user(12, "user21", "user21@c.com"));     users.add(new user(8, "user2", "user2@c.com"));     users.add(new user(1, "admin1", "admin1@c.com"));     users.add(new user(3, "admin10", "admin10@c.com"));     users.add(new user(2, "admin2", "admin2@c.com"));     users.add(new user(9, "user10", "user10@c.com"));     users.add(new user(4, "admin11", "admin11@c.com"));      (user item : users) {         system.out.println(item.getemail());     }      system.out.println("__________________________");      collections.sort(users, new fieldcomparator(user.class, "email"));      (user item : users) {         system.out.println(item.getemail());     }      system.out.println("__________________________");      collections.sort(users, new fieldcomparator(user.class, "name"));      (user item : users) {         system.out.println(item.getemail());     }      system.out.println("__________________________");      collections.sort(users, new fieldcomparator(user.class, "id"));      (user item : users) {         system.out.println(item.getemail());     } } 

Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -