I'm reading a text file into a 2D array. The first column ( the one I'm sorting on) is almost all Doubles. As you all probably know, it sorts 1.1 1.6 25.6 6.4, how can I fix this?
import java.io.*;
import java.util.*;
public class Sort {
public static void main(final String[] args) throws FileNotFoundException {
FileOutputStream out = new FileOutputStream("/Users/evanlivingston/2d.txt");
PrintStream pout = new PrintStream(out);
List<String[]> entries = new ArrayList<String[]>();
Scanner sc = new Scanner(new File("/Users/evanlivingston/dists/0.txt"));
while (sc.hasNext()) {
entries.add(new String[] { sc.next(), sc.next()});
}
String[][] table = entries.toArray(new String[0][]);
Arrays.sort(table, new Comparator<String[]>() {
@Override
public int compare(String[] s1, String[] s2) {
String t1 = s1[0];
String t2 = s2[0];
return t1.compareTo(t2);
}
});
pout.print(java.util.Arrays.deepToString(table));
pout.close();
}
}
EDIT:
Here is my upda开发者_C百科ted code. It won't compile.import java.io.*;
import java.util.*;
public class Sort {
public static void main(String[] args) throws FileNotFoundException {
FileOutputStream out = new FileOutputStream("/Users/evanlivingston/2d.txt");
PrintStream pout = new PrintStream(out);
List<Coords> coords = new ArrayList<Coords>();
{
Scanner sc = new Scanner(new File("/Users/evanlivingston/dists/0.txt"));
while(sc.hasNextLine()) {
String[] numstrs = sc.nextLine().split("\\s+");
}
String[][] table = coords.toArray(new String[0][]);
Arrays.sort(table, new Comparator<Double[]>() {
@Override
public int compare(Double[] s1, Double[] s2) {
double a = Double.parseDouble(s1);
double b = Double.parseDouble(s2);
compare(a, b);
}
});
pout.print(java.util.Arrays.deepToString(table));
pout.close();
}
}
}
Store doubles in the array NOT Strings.
So convert the String to a double when you read it in from your file. Or use the Scanner.nextDouble() method to do this for you.
You don't want to be converting the Strings every time the Comparator is invoked.
You're comparing strings, not numeric values. 1 is lexically lower than 2, and 2 is lexically lower than three. So from a string perspective, 234 is less than 3. You have to convert your doubles
from strings
in order to compare them properly. In Java you do this via:
double aDouble = Double.parseDouble(aString);
so your final expression should really be
double a = Double.parseDouble(firstString);
double b = Double.parseDouble(secondString);
compare(a,b);
You're comparing String
values, not Double
values, so 2 comes after 1 and before 6.
To fix this, you should convert your values to actual Double
objects with the wrapper method valueOf()
(documentation).
EDIT:
I went for the simpler fix above, but camickr's answer is better if you care at all about performance.
Regarding your update not compiling, multiple things are wrong. Did you ever declare a second compare()
method anywhere? There's nothing built in for that. Recursively calling the existing compare()
won't help in your case.
On that note, you can't call the existing compare()
; autoboxing won't convert primitive double
s into arrays of Double
objects. And there's no way to parse Double
arrays into primitive double
s.
Since you're trying to use primitive double
s now, you could just use the plain old >
and <
operators to compare with instead of the more complex Comparator
stuff.
Have your comparator convert the strings it is input into doubles and do a numeric comparison rather than a string compare.
That's the advantage of the Comparator
concept. It can do anything with the inputs. So if you need to sort Strings
as if they were numbers, write a Comparator
that'll do just that.
精彩评论