JTable DefaultRowSorter sortiert Strings und Floats nicht richtig

Hallo, Folgendes klappt nicht richtig:

ArrayList<CarsAndSizes> list = new ArrayList<>(m.map.values());
// Collections.sort(list);
Object[][] oa = new Object[list.size()][3];
int i = 0;
for (CarsAndSizes c : list) {
	oa[i][0] = c.p.toString();
	oa[i][1] = (int) c.car;
	oa[i][2] = (float) (c.size / 1000000F);
	i++;
}

DefaultTableModel model = new DefaultTableModel(oa, new String[] { "Path", "Cars", "Sizes" }) {
	private static final long serialVersionUID = 1L;

	@SuppressWarnings({})
	@Override
	public Class<?> getColumnClass(int column) {
		switch (column) {
		case 0:
			return String.class;
		case 1:
			return Integer.class;
		case 2:
			return Float.class;
		default:
			return String.class;
		}
	}
};
for (int k = model.getRowCount() - 1; k >= 0; k--) {
	if ((Integer) model.getValueAt(k, 1) == 0)
		model.removeRow(k);
}
JTable table = new JTable(model);
JScrollPane scroll = new JScrollPane(table);
table.setAutoCreateRowSorter(true);
DefaultRowSorter<?, ?> sorter = (DefaultRowSorter<?, ?>) table.getRowSorter();
// sorter.setMaxSortKeys(3);
sorter.setSortKeys(Arrays.asList(
		new RowSorter.SortKey(2, SortOrder.DESCENDING),
		new RowSorter.SortKey(1, SortOrder.DESCENDING),
		new RowSorter.SortKey(0, SortOrder.ASCENDING)));
sorter.sort();

JFrame frame = new JFrame();
frame.add(scroll);
frame.setSize(800, 800);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
class CarsAndSizes {
	Path p;
	int car;
	long size;

	CarsAndSizes(Path p, int car, long size) {
		this.p = p;
		this.car = car;
		this.size = size;
	}
}

L wird bei gleichen int und float zwischen D sortiert.

Mit einem Comparable in CarsAndSizes und ohne setSortKeys sortiert er richtig:

class CarsAndSizes implements Comparable<CarsAndSizes> {
	Path p;
	int car;
	long size;

	CarsAndSizes(Path p, int car, long size) {
		this.p = p;
		this.car = car;
		this.size = size;
	}

	@Override
	public int compareTo(CarsAndSizes o) {
		long s1 = (long) (size / 1000f);
		long s2 = (long) (o.size / 1000f);

		if (s1 == s2) {
			if (car == o.car) {
				return p.compareTo(o.p);
			} else {
				return Integer.compare(o.car, car);
			}
		}
		return Long.compare(s2, s1);
	}
}

Weiß jemand woran das liegen könnte, ist die interne float-Darstellung vielleicht anders, als die in der JTable angezeigten?

Ja, daran liegt’s denn die JTable rundet in irgendeiner Form die floats… und mit einer zusätzlichen Column, geht es besser:

ArrayList<CarsAndSizes> list = new ArrayList<>(m.map.values());
Object[][] oa = new Object[list.size()][4];
int i = 0;
for (CarsAndSizes c : list) {
	oa[i][0] =         c.p.toString();
	oa[i][1] = (int)   c.car;
	oa[i][2] = (long) (c.size / 1000L);
	oa[i][3] = (int)  (c.size % 1000L);
	i++;
}

DefaultTableModel model = new DefaultTableModel(oa, new String[] { "Path", "Cars", "KB", "bytes" }) {
	private static final long serialVersionUID = 1L;

	@SuppressWarnings({})
	@Override
	public Class<?> getColumnClass(int column) {
		switch (column) {
		case 0:
			return String.class;
		case 1:
			return Integer.class;
		case 2:
			return Long.class;
		case 3:
			return Integer.class;
		default:
			return String.class;
		}
	}
};

JTable table = new JTable(model);
JScrollPane scroll = new JScrollPane(table);
table.setAutoCreateRowSorter(true);
DefaultRowSorter<?, ?> sorter = (DefaultRowSorter<?, ?>) table.getRowSorter();
sorter.setSortKeys(Arrays.asList(
		new RowSorter.SortKey(2, SortOrder.DESCENDING),
		new RowSorter.SortKey(1, SortOrder.DESCENDING),
		new RowSorter.SortKey(0, SortOrder.ASCENDING)));
sorter.sort();
for (int k = model.getRowCount() - 1; k >= 0; k--) {
	if ((Integer) model.getValueAt(k, 1) == 0)
		model.removeRow(k);
}
table.getColumnModel().getColumn(0).setPreferredWidth(600);

Vielleicht wisst ihr, wie eine JTable Fließkommazahlen „rundet“… (es wird auch teils aufgerundet).

Edit:
Es hängt von der Locale ab, bei mir ist es ‚rounding to nearest (half even) with 3 fraction digits‘ (vs. ‚rounding towards zero‘).