I am trying to read data in from a CSV file containing 4 columns to an array list. Let's call the columns a,b,c,d (They each contain integers). Then I would like to sort the array list according to the contents of the rows of a,b,c,d.
So if you are comparing row 1 and 2 for example, if the value of 1d<2d then return a certain value. If 1d=2d then compare 1c to 2c and so on. I am having trouble with finding a way to create an array list that allows me to differentiate and compare each row/column.
public class Speed {
public static void main(String[] args) throws IOException {
// TODO code application logic here
readCSV();
}
public static void readCSV() throws FileNotFoundException, IOException {
BufferedReader br = new BufferedReader(new FileReader("amis.csv"));
String line = "";
ArrayList<String> amis = new ArrayList<String>();
while ((line = br.readLine()) != null) {
line = line.replaceAll("\"", "");
amis.add(line);
}
amis.remove(0);
for (String alphabet: amis) {
Object[] parts = alphabet.split(",");
Object studentID = (parts[0]);
Object a = parts[1];
Object b = parts[2];
Object c = (parts[3]);
Object d = parts[4];
ArrayList<Object> Compare = new ArrayList();
Compare.add(a);
Compare.sort(new customComparator());
}
My custom comparator class
public class customComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) {
int a = (Integer) o1;
int b = (Integer) o2;
if (a < b) {
return 1;
}
else if(a > b)
return -1;
else
return 0;
}
}
Let's take a look at your current sorting method
for(String alphabet: amis)
{
Object[] parts = alphabet.split(",");
Object studentID = (parts[0]);
Object a = parts[1];
Object b = parts[2];
Object c = (parts[3]);
Object d = parts[4];
ArrayList<Object> Compare = new ArrayList();
Compare.add(a);
Compare.sort(new customComparator());
}
The most blatant issue is you're creating an ArrayList, Compare, adding/sorting, then discarding it
If you're trying to make a second, sorted list:
List<String> sorted = new ArrayList<String>(amis);
sorted.sort(new CustomComparator());
If you're just trying to sort the original list:
amis.sort(new CustomComparator());
You've gotten fairly close to what you want to do, by making a comparator, but it needs tweaking
Your current implementation stops after it checks the first value, it returns 0 instead of continuing
public class CustomComparator implements Comparator<String>
{
public int compare(String A, String B)
{
String[] as = A.split(",");
String[] bs = B.split(",");
int a = Integer.parseInt(a[4]); //column d, as an int
int b = Integer.parseInt(b[4]);
if(a < b)
return 1;
else
if(a > b)
return -1;
else
{
a = Integer.parseInt(a[3]); //column c, as an int
b = Integer.parseInt(b[3]);
if(a < b)
return -1;
else
if(a > b)
return 1;
else
{
a = Integer.parseInt(a[2]); //column b, as an int
b = Integer.parseInt(b[2]);
if(a < b)
return -1;
else
if(a > b)
return 1;
else
{
a = Integer.parseInt(a[1]); //column a, as an int
b = Integer.parseInt(b[1]);
if(a < b)
return -1;
else
if(a > b)
return 1;
else
return 0; //all columns are the same
}
}
}
}
}
Noticing that there is a lot of similar code, we can instead change it into a loop
public int compare(String A, String B)
{
String[] as = A.split(",");
String[] bs = B.split(",");
for(int i = 4; i >= 1; i--) //columns d-a
{
int a = Integer.parseInt(a[i]);
int b = Integer.parseInt(b[i]);
if(a < b)
return -1;
if(a > b)
return 1;
}
return 0;
}
You should rather create POJO for each string and comparator for it. In the comparator you should compare more "important" columns first and go to less important if previous are equal.
public class Pojo {
private int a;
private int b;
private int c;
private int d;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public int getC() {
return c;
}
public void setC(int c) {
this.c = c;
}
public int getD() {
return d;
}
public void setD(int d) {
this.d = d;
}
public static class PojoComparator implements Comparator<Pojo> {
#Override
public int compare(Pojo pojo1, Pojo pojo2) {
return pojo1==null ? (pojo2==null ? 0:1) :(pojo2==null?-1:
(pojo1.d!=pojo2.d? pojo1.d-pojo2.d :
(pojo1.c!=pojo2.c ? pojo1.c-pojo2.c:
(pojo1.b!=pojo2.b? pojo1.b-pojo2.b:
pojo1.a-pojo2.a))) );
}
}
}
Related
I am not sure if the title to this question is correct.
I have this school assignment where we have to create two classes.
In one class, we define relationships between people e.g. A knows B, and in the other class we ask questions about that, e.g. does A know B?
The first class below defines relationships and gives methods, the second class inquires about them.
I am sure that my mistake lies somewhere in the public boolean 'knowsWithDegree'. Are you able to help?
public class SocialGraph {
private HashMap<String, List<String>> map = new HashMap<String, List<String>>();
public SocialGraph() { // empty constructor
map = new HashMap<String, List<String>>();
}
public void addIndividual(String a) {
if (!map.containsKey(a)) {
map.put(a, new ArrayList<String>());
} else {
}
}
public boolean hasKnowsArrow(String a, String b) {
if (map.containsKey(a)) {
return map.get(a).contains(b);
} else {
return false;
}
}
public void addKnowsArrow(String a, String b) {
if ((!map.containsKey(a) || !map.containsKey(b)) || (hasKnowsArrow(a, b))) {
} else {
map.get(a).add(b);
}
}
public void removeKnowsArrow(String a, String b) {
if ((!map.containsKey(a) || !map.containsKey(b)) || (!hasKnowsArrow(a, b))) {
} else {
map.get(a).remove(b);
}
}
public boolean knowsWithDegree(String a, String b, int x) {
Object[] keys = map.keySet().toArray();
int y;
y = 0;
if (map.get(a).contains(b)) {
y = 1;
} else {
if ((map.get(a).contains(map.get(keys[0]).contains(b))) || (map.get(a).contains(map.get(keys[1]).contains(b))) ||
(map.get(a).contains(map.get(keys[2]).contains(b))) || (map.get(a).contains(map.get(keys[3]).contains(b)))) {
y = 2;
}
}
if (x == y) {
return true;
} else
return false;
}
}
public class SocialGraphTest {
public static void main(String[] args) {
SocialGraph socialGraph = new SocialGraph();
socialGraph.addIndividual("Anne");
socialGraph.addIndividual("Daisy");
socialGraph.addIndividual("Bob");
socialGraph.addIndividual("Charlie");
socialGraph.addKnowsArrow("Anne", "Bob");
socialGraph.addKnowsArrow("Anne", "Daisy");
socialGraph.addKnowsArrow("Bob", "Daisy");
socialGraph.addKnowsArrow("Bob", "Charlie");
System.out.println(socialGraph.hasKnowsArrow("Anne", "Bob")); //should be true
System.out.println(socialGraph.hasKnowsArrow("Anne", "Daisy"));//should be true
System.out.println(socialGraph.hasKnowsArrow("Bob", "Daisy"));//should be true
System.out.println(socialGraph.hasKnowsArrow("Bob", "Charlie"));//should be true
System.out.println(socialGraph.hasKnowsArrow("Anne", "Charlie")); //should be false
System.out.println ();
System.out.println (socialGraph.knowsWithDegree ("Anne", "Daisy", 1));
System.out.println (socialGraph.knowsWithDegree ("Anne", "Charlie", 2));
System.out.println (socialGraph.knowsWithDegree ("Anne", "Daisy", 3));
}
}
}
Here is an example using recursion:
public boolean knowsWithDegree(String a, String b, int x) {
return knowsWithDegreeRecursive(a, b, x, new HashSet<>());
}
private boolean knowsWithDegreeRecursive(String a, String b, int x, Set<String> visited) {
if (x < 1) {
// x must be at least 1
return false;
}
if (map.get(a).contains(b)) {
// If a knows b, then the number of degrees should be 1
return x == 1;
}
if (x == 1) {
// Since the degree is 1 and a does not know b, then a does not know b to the specified degree
return false;
}
// Go through each person that a knows
for (String c : map.get(a)) {
if (visited.contains(c)) {
// We've already checked this person
continue;
}
// Mark c as visited so we don't check them again
visited.add(c);
// See if this person knows b, with one fewer degree
// e.g. if we're seeing if a knows b with a degree of 2, then c should know b with a degree of 1
boolean knowsWithDegree = knowsWithDegreeRecursive(c, b, x - 1, visited);
// If c knows b with the degree minus 1, then a knows b with the specified degree
if (knowsWithDegree) {
return true;
}
}
// a does not know b to the specified degree
return false;
}
If the order of the knowsArrows doesn't matter, I would recommend using HashSet in your map over ArrayList.
I am trying to check whether my levelorder of my Binary Search Tree is equal to the other one. To do this, I tried to make a compareTo method. I only give equal values to the method, but it keeps on saying the condition is false. When I place breakpoints, I see that the values are still equal. I am probably not understanding it correctly. Does anyone know how to solve this?
Here is what I did, as you can see below, the compareTo returns a 1 instead of a 0:
import edu.princeton.cs.algs4.BST;
import java.util.*;
public class MyBST implements Comparable<MyBST>{
private Object e;
public MyBST(Object e){
this.e = e;
}
private Object getE(){
return e;
}
public static void main(String[] args) {
int size = 4;
Random r = new Random();
Set<Integer> tes = new LinkedHashSet<>(size);
Stack<Integer> stack = new Stack<>();
while (tes.size() < size) {
tes.add(r.nextInt(10));
}
System.out.println("possible combinations");
Set<Stack<Integer>> combos = combos(tes, stack, tes.size());
Object[] arr = combos.toArray();
List<String> d = new ArrayList<>();
for (Object s : arr) {
String b = s.toString();
b = b.replaceAll("\\[", "").replaceAll("\\]", "");
d.add(b);
}
int index = 0;
do {
BST<String, Integer> bst1 = new BST<String, Integer>();
BST<String, Integer> bst2 = new BST<String, Integer>();
String key1 = d.get(index);
String key2 = d.get(index);
key1 = key1.replaceAll(" ", "");
String[] m = key1.split(",");
key2 = key2.replaceAll(" ", "");
String[] n = key2.split(",");
System.out.println("1e order");
for (int j = 0; j < m.length; j++) {
System.out.println(m[j]);
bst1.put(m[j], 0);
}
System.out.println("2e order");
for (int j = 0; j < n.length; j++) {
System.out.println(n[j]);
bst2.put(n[j], 0);
}
System.out.println("levelorder 1e BST");
MyBST e = new MyBST(bst1.levelOrder());
MyBST y = new MyBST(bst2.levelOrder());
System.out.println(bst1.levelOrder());
System.out.println("levelorder 2e BST");
System.out.println(bst2.levelOrder());
System.out.println(e.compareTo(y) + "\n");
index++;
} while (index < arr.length - 1);
}
public static Set<Stack<Integer>> combos(Set<Integer> items, Stack<Integer> stack, int size) {
Set<Stack<Integer>> set = new HashSet<>();
if (stack.size() == size) {
set.add((Stack) stack.clone());
}
Integer[] itemz = items.toArray(new Integer[0]);
for (Integer i : itemz) {
stack.push(i);
items.remove(i);
set.addAll(combos(items, stack, size));
items.add(stack.pop());
}
return set;
}
#Override
public int compareTo(MyBST o) {
if (this.e == o.e) {
return 0;
}
else
return 1;
}
}
Here you can find the BST.java class: BST.java
And the output is something like:
The breakpoint at the compareTo method says:
When you're using the == operator you're actually checking to see if the references point to the same object in memory. From your debugging screenshot you can see that they are not. this.e points to object Queue#817 while o.e points to Queue#819.
If all you want to do is test for equality, then just override equals and hashCode. You can do it like this (rest of class omitted):
public class MyBST {
private Object e;
public MyBST(Object e) {
this.e = e;
}
public Object getE(){
return e;
}
#Override
public int hashCode() {
return Objects.hashCode(e);
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof MyBST))
return false;
MyBST me = (MyBST) obj;
if (e == null) {
if (me.e != null)
return false;
} else if (!e.equals(me.e))
return false;
return true;
}
}
Implementing Comparable is more involved since you need to check for less, equal, or greater than other instances of MyBST. Unfortunately, the only field in MyBST is an Object which does not tell you anything about its actual fields. So without specific fields with which to test you need to ensure that the Object you pass also implements Comparable. Then you can declare your class like this. Rest of class omitted.
It simply says that
MyBST is comparable.
And the object that is passed in the constructor is comparable.
class MyBST<T extends Comparable<? super T>> implements Comparable<MyBST<T>>{
private T e;
public MyBST(T e){
this.e = e;
}
public T getE(){
return e;
}
#Override
public int compareTo(MyBST<T> o) {
return e.compareTo(o.e);
}
}
The other alternative is to simply pass the actual object type and store it as such, not as Object. Then just implement Comparable in MyBST and use the appropriate fields of the passed object. Lets say the object was an Apple object, you could do this.
class Apple {
String type;
int weight;
}
class MyBST implements Comparable<MyBST> {
private Apple apple;
public MyBST(Apple apple) {
this.apple = apple;
}
#Override
public int compareTo(MyBST e) {
// this could be different depending on how you wanted
// to compare one apple to another. This comparison favors
// type over weight.
// check type - String class implements comparable
int ret = apple.type.compareTo(e.apple.type);
if (ret != 0) {
return ret;
}
// same type so check weight
if (apple.weight < e.apple.weight) {
return -1;
}
if (apple.weight > e.apple.weight) {
return 1;
}
return 0; // equals apples based on criteria
}
}
Finally, you have this.
private Object getE(){
return e;
}
A private getter is not usually very useful. Make it public.
I have a quick question. How would I find the most common character in a string in Java. I know logically how to do it, but I am not sure if my syntax in correct:
public class HelloWorld {
public static void main(String[] args){
String votes = "ABBAB";
char[] StoringArray = votes.toCharArray();
int numOFB = 0;
int numOFA = 0;
if (StoringArray.contains("A")) {
numOFA++;
} else if (StoringArray.contains("B")) {
numOFAB++;
}
if (numOFA = numOFB) {
System.out.println("Tie");
} else if (numOFA > B) {
System.out.println("A");
} else {
System.out.println("B");
}
}
}
Could anyone help me with how to correctly do this in Java?
You can not compare char Array with string, below logic should work and give you what you need:
public static void main(String[] args){
String votes = "ABBAB";
char[] storingArray = votes.toCharArray();
int numOFB = 0;
int numOFA = 0;
for(char c : storingArray) {
if(c == 'A') {
numOFA++;
}
if(c == 'B') {
numOFB++;
}
}
if (numOFA == numOFB) {
System.out.println("Tie");
} else if (numOFA > numOFB) {
System.out.println("A");
} else {
System.out.println("B");
}
}
There are couple of mistakes in your code:
You can not use if (numOFA = numOFB) it is not valid expression. You should use == to compare
You can not compare char Array with contains method. It should be used on String object
As the comments said; it looks like you're counting the number of A's or B's, not the longest substring. Are you only analyzing a String composed of A's and B's?
Also, you're using = to check for equality when you should be using ==. I would recommend using an IDE like Eclipse which would show you when you're doing this.
Edit: also, you're not looping through the array. You're just checking if the String contains an A or a B and adding 1 if it does. You need to loop through the entire array.
Actually, I was working with it, and I found this is the nicest way to do it:
String votes = "ABBAB";
char[] StoringArray = votes.toCharArray();
int B = 0;
int A = 0;
for (int i = 0; i < StoringArray.length; i ++) {
if (StoringArray[i] == 'A') {
A++;
} else if (StoringArray[i] == 'B') {
B++;
}
}
if (A == B) {
System.out.println("Tie");
} else if (A > B) {
System.out.println("A");
} else {
System.out.println("B");
}
I would give you a more abstract solution:
public class Counter{
private char c;
private int count;
Counter(char c, int count){
this.c=c;
this.count=count;
}
public char getC() {
return c;
}
public void setC(char c) {
this.c = c;
}
public int getCount() {
return count;
}
public void addOcurrence() {
this.count++;
}
#Override
public boolean equals(Object obj) {
if(obj!=null)
if(((Counter)obj).getC()== this.c)
return true;
return false;
}
}
public static void main(String[] args){
String votes = "whateveryouwanttoputhereorcanbefromaparameter";
char[] storingArray = votes.toCharArray();
List<Counter> listCounter = new ArrayList<Counter>();
for(char aChar : storingArray){
Counter compareCounter = new Counter(aChar,1);
if(listCounter.contains(compareCounter)){
listCounter.get(listCounter.indexOf(compareCounter)).addOcurrence();
}else{
listCounter.add(compareCounter);
}
}
Counter max = listCounter.get(0);
for( Counter c : listCounter){
if(c.getCount() > max.getCount()){
max = c;
}
}
System.out.println("the character with more ocurrence is: "+max.getC());
}
I came across a post showing how to arrange char array by alphabet order.
seeing this can be done, I want to output the alphabetical order of each character of the input string, in order of the characters of the input string.
I'm a bit stuck. I can get the string reordered alphabetically, but I don't know what to do next.
example is 'monkey' to '354216'
because 'ekmnoy' e is alphabetically first from the set of given characters so e = 1 , k is the second alpha char when sorted so k = 2, and so on.
if you cannot understand I can provide more example to make things clear out.
Code
String str = "airport";
Character[] chars = new Character[str.length()];
for (int z = 0; z < chars.length; z++) {
chars[z] = str.charAt(z);
}
Arrays.sort(chars, new Comparator<Character>() {
public int compare(Character c1, Character c2) {
int cmp = Character.compare(
Character.toLowerCase(c1.charValue()),
Character.toLowerCase(c2.charValue()));
if (cmp != 0) {
return cmp;
}
return Character.compare(c1.charValue(), c2.charValue());
}
});
StringBuilder sb = new StringBuilder(chars.length);
for (char c : chars) {
sb.append(c);
}
str = sb.toString();
System.out.println(sb);
Output
aioprrt
expected output
Orange -> aegnOr
561432 - 123456
Monkey -> ekMnoy
354216 -> 123456
I dont know what you want to do with double characters, but if you add this few lines to your code at the end you are getting the right result. Iterate over the sorted String and replace the charakters in the original String with their indices in the sorted String.
String originalStr = "airport";
for(int i = 0; i<str.length(); i++) {
originalStr = originalStr.replace(str.charAt(i), String.valueOf(i+1).charAt(0));
}
System.out.println(originalStr);
Output: 1254357
If you want to get the output: 1254367 use replaceFirst:
originalStr = originalStr.replaceFirst(String.valueOf(str.charAt(i)), String.valueOf(i+1));
Input:Orange
Output:561432
Input:Monkey
Output:354216
The whole code:
String str = "airport";
String originalStr = str; //creat a backup of str because you change it in your code
Character[] chars = str.toCharArray();
Arrays.sort(chars, new Comparator<Character>() {
public int compare(Character c1, Character c2) {
int cmp = Character.compare(
Character.toLowerCase(c1.charValue()),
Character.toLowerCase(c2.charValue()));
if (cmp != 0) {
return cmp;
}
return Character.compare(c1.charValue(), c2.charValue());
}
});
str = String.valueOf(chars);
System.out.println(str);
//Iterate over the sorted String and replace the charakters in the original String with their indices in the sorted String
for(int i = 0; i<str.length(); i++) {
originalStr = originalStr.replaceFirst(String.valueOf(str.charAt(i)), String.valueOf(i+1));
}
System.out.println(originalStr);
Once you have arranged the characters in order (in a different array from the original) then create a third array by walking the original string and choosing the index of each character from te sorted string.
input: edcba
sorted: abcde
index: 01234
Pseudocode...
for( int i = 0; i < input.length(); i++ ) {
index[i] = sorted.indexOf(input[i]);
}
Result should be 43210 with the given input.
Note that strings with more than 10 characters will result in ambiguous output, which can be handled by inserting spaces in the output. Example:
abcdefghijk ->
012345678910
You can use this below code:
package Test;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class Arrange {
public static void main(String[] args) {
String str = "money";
List<Test> strs=new LinkedList<Test>();
List<Test> final_result=new LinkedList<Test>();
for(int i=0;i<str.length();i++)
{
Test t=new Test(i, ""+str.charAt(i), 0);
strs.add(t);
}
Collections.sort(strs,new Comparator<Test>() {
#Override
public int compare(Test o1, Test o2) {
return (o1.getS().compareToIgnoreCase(o2.getS()));
}
});
Integer i=1;
for (Test st : strs) {
st.setJ(i);
final_result.add(st);
i++;
}
Collections.sort(final_result,new Comparator<Test>() {
#Override
public int compare(Test o1, Test o2) {
return (o1.getI().compareTo(o2.getI()));
}
});
for (Test test : final_result) {
System.out.println(test.getJ());
}
}
}
class Test{
private Integer i;
private String s;
private Integer j;
public Test() {
// TODO Auto-generated constructor stub
}
public Test(Integer i, String s, Integer j) {
super();
this.i = i;
this.s = s;
this.j = j;
}
public Integer getI() {
return i;
}
public void setI(Integer i) {
this.i = i;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public Integer getJ() {
return j;
}
public void setJ(Integer j) {
this.j = j;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((i == null) ? 0 : i.hashCode());
result = prime * result + ((j == null) ? 0 : j.hashCode());
result = prime * result + ((s == null) ? 0 : s.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;
Test other = (Test) obj;
if (i == null) {
if (other.i != null)
return false;
} else if (!i.equals(other.i))
return false;
if (j == null) {
if (other.j != null)
return false;
} else if (!j.equals(other.j))
return false;
if (s == null) {
if (other.s != null)
return false;
} else if (!s.equals(other.s))
return false;
return true;
}
}
What would be the best and most efficient way to sort a Java Vector in JAVAME.
My object has five properties, and I would like to sort by a property called price which is of type double. In my Vector I will have a maximum of 150 items. A sample code would be appreciated.
Thanx for your time.
Use Collections.sort(List<T> vector, Comparator<T> c) method. If there is no such method in Java ME, just copy it from Java SE. It uses merge sort algorithm, so it will not be much to copy.
import java.lang.reflect.Field;
import java.util.*;
public class Sorter {
public static List sort(List list, String fieldName, boolean asc) {
Comparator c = new FieldComparator(fieldName, asc);
Collections.sort(list, c);
return list;
}
public static int compareNumbers(Number n1, Number n2) {
double d1 = n1.doubleValue();
double d2 = n2.doubleValue();
if (d1 < d2) {
return -1;
}
if (d2 < d1) {
return 1;
}
return 0;
}
public static int compareDates(Date d1, Date d2) {
long l1 = d1.getTime();
long l2 = d2.getTime();
if (l1 < l2) {
return -1;
}
if (l2 < l1) {
return 1;
}
return 0;
}
public static int compareStrings(String s1, String s2) {
return s1.compareTo(s2);
}
public static Object getFieldValue(Object obj, String fn) {
try {
Class clazz = obj.getClass();
Field f = null;
try {
f = clazz.getDeclaredField(fn);
} catch (Exception e) {}
while (f == null && clazz.getSuperclass() != null) {
clazz = clazz.getSuperclass();
try {
f = clazz.getDeclaredField(fn);
} catch (Exception e) {}
}//while
if (f != null) {
f.setAccessible(true);
return f.get(obj);
}
} catch (IllegalAccessException e) {}
return null;
}
protected static class FieldComparator implements Comparator {
String fieldName;
int asc;
protected FieldComparator(String fieldName, boolean asc) {
this.fieldName = fieldName;
this.asc = asc ? 1 : -1;
}
public int compare(Object o1, Object o2) {
if (o1 == null) {
if (o2 == null) {
return 0;
} else {
return -1 * asc;
}
}
if (o2 == null) {
return asc;
}
//compare fields
Object fieldValue1 = getFieldValue(o1, fieldName);
Object fieldValue2 = getFieldValue(o2, fieldName);
if (fieldValue1 == null) {
if (fieldValue2 == null) {
return 0;
} else {
return -1 * asc;
}
}
if (fieldValue2 == null) {
return asc;
}
//both field values aren't nulls
if (fieldValue1 instanceof Number && fieldValue2 instanceof Number) {
return compareNumbers((Number) fieldValue1, (Number) fieldValue2) * asc;
} else if (fieldValue1 instanceof Date && fieldValue2 instanceof Date) {
return compareDates((Date) fieldValue1, (Date) fieldValue2) * asc;
} else {
return compareStrings(fieldValue1.toString(), fieldValue2.toString()) * asc;
}
}
}
public static void main(String[] args) {
ArrayList source = new ArrayList();
source.add(new TestNumber(5));
source.add(new TestNumber(1));
source.add(new TestNumber(4));
source.add(new TestNumber(2));
source.add(new TestNumber(3));
List dest = sort(source, "value", true);
out(dest);
source = new ArrayList();
source.add(new TestString("cc"));
source.add(new TestString("dd"));
source.add(new TestString("bb"));
source.add(new TestString("ee"));
source.add(new TestString("aa"));
dest = sort(source, "value", false);
out(dest);
}
private static class TestNumber {
private int value;
public TestNumber(int v) {
value = v;
}
public String toString() {
return "" + value;
}
}
private static class TestString {
private String value;
public TestString(String v) {
value = v;
}
public String toString() {
return "" + value;
}
}
private static void out(List list) {
for (Object obj : list) {
System.out.println("" + obj.toString());
}
System.out.println("----------------------------");
}
}
Adjusted code from JavaSE:
public static void sort(List<YourObject> list) {
Object[] a = list.toArray();
sort(a);
ListIterator<YourObject> i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set((YourObject)a[j]);
}
}
public static void sort(YourObject[] a) {
YourObject[] aux = (YourObject[])a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
private static void mergeSort(YourObject[] src,
YourObject[] dest,
int low,
int high,
int off) {
int length = high - low;
// Insertion sort on smallest arrays
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; i<high; i++)
for (int j=i; j>low &&
dest[j-1].getPrice()-dest[j].getPrice()>0; j--)
swap(dest, j, j-1);
return;
}
// Recursively sort halves of dest into src
int destLow = low;
int destHigh = high;
low += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off);
mergeSort(dest, src, mid, high, -off);
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
if (src[mid-1].getPrice()-src[mid].getPrice() <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
// Merge sorted halves (now in src) into dest
for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && src[p].getPrice()-src[q].getPrice()<=0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}