Tôi có thể làm hỏng bài tập về nhà một số học sinh, nhưng ở đây đi ...
Như đã đề cập về Câu hỏi, cách tự nhiên trong Java là để tạo ra một lớp đại diện cho dữ liệu của bạn. Sau đó, triển khai Comparator
để chuyển sang phương thức tiện ích Collections.sort
.
Trên MacBook Pro 2.3 GHz của tôi Intel Core i7 chạy một máy ảo Parallels với Java 8, một bộ dữ liệu gồm 42.000 phần tử mất khoảng 45-90 mili giây để sắp xếp.
Tôi đã thay đổi dữ liệu mẫu của bạn trở nên thú vị hơn, giới thiệu một số ngày khác nhau và vĩ độ trùng lặp.
20000101,34.6920,-116.3550,12.30,1.21
20000101,34.4420,-116.2280,7.32,1.01
20000101,34.6920,-121.7667,5.88,1.14
20000101,-41.1300,174.7600,27.00,1.90
20000101,37.6392,-119.0482,2.40,1.03
20000101,32.1790,-115.0730,6.00,2.44
20000101,34.6920,-152.2192,86.34,1.48
20000102,34.6320,-116.2410,11.63,1.61
20000102,59.5369,-153.1360,100.15,1.62
20000102,44.7357,-110.7932,4.96,2.20
20000102,34.6320,-116.2950,9.00,1.73
20000102,34.6320,-110.7938,5.32,1.75
20000102,34.6320,-117.6320,4.15,1.45
20000102,41.9270,20.5430,10.00,4.80
Lớp GeoReading
của tôi đại diện cho dữ liệu.
class GeoReading
{
LocalDate localDate = null;
BigDecimal latitude = null;
BigDecimal longitude = null;
BigDecimal depth = null;
BigDecimal magnitude = null;
public GeoReading(String arg)
{
// String is comma-separated values of: Date,Lat,Lon,Depth,Mag
List<String> items = Arrays.asList(arg.split("\\s*,\\s*")); // Regex explained here: http://stackoverflow.com/a/7488676/642706
this.localDate = ISODateTimeFormat.basicDate().parseLocalDate(items.get(0));
this.latitude = new BigDecimal(items.get(1));
this.longitude = new BigDecimal(items.get(2));
this.depth = new BigDecimal(items.get(3));
this.magnitude = new BigDecimal(items.get(4));
}
@Override
public String toString()
{
return "GeoReading{" + "localDate=" + localDate + ", latitude=" + latitude + ", longitude=" + longitude + ", depth=" + depth + ", magnitude=" + magnitude + '}';
}
}
Dưới đây là triển khai So sánh.
class GeoReadingAscendingComparator implements Comparator<GeoReading>
{
@Override
public int compare(GeoReading o1 , GeoReading o2)
{
int localDateCompare = o1.localDate.compareTo(o2.localDate);
if (localDateCompare != 0) { // If not equal on this component, so compare on this.
return localDateCompare;
}
int latitudeCompare = o1.latitude.compareTo(o2.latitude);
if (latitudeCompare != 0) { // If not equal on this component, so compare on this.
return latitudeCompare;
}
return o1.longitude.compareTo(o2.longitude);
}
}
Mã chính.
Path path = Paths.get("/Users/basil/lat-lon.txt"); // Path for Mac OS X.
try {
List<GeoReading> list = new ArrayList<>();
Stream<String> lines = Files.lines(path);
lines.forEach(line -> list.add(new GeoReading(line)));
// Take those 14 lines and multiply to simulate large text file. 14 * 3,000 = 42,000.
int count = 3000;
List<GeoReading> bigList = new ArrayList<>(list.size() * count); // Initialze capacite to expected number of elements.
for (int i = 0 ; i < count ; i++) {
bigList.addAll(list);
}
long start = System.nanoTime();
Collections.sort(bigList , new GeoReadingAscendingComparator());
long elapsed = (System.nanoTime() - start);
System.out.println("Done sorting the GeoReading list. Sorting " + bigList.size() + " took: " + TimeUnit.MILLISECONDS.convert(elapsed , TimeUnit.NANOSECONDS) + " ms (" + elapsed + " nanos).");
System.out.println("Dump…");
for (GeoReading g : bigList) {
System.out.println(g);
}
} catch (IOException ex) {
System.out.println("ERROR - ex: " + ex);
}
Trong thế giới thực, tôi sẽ thêm một số mã lập trình phòng thủ để xác minh dữ liệu đến. Dữ liệu từ các nguồn bên ngoài là luôn luôn bị lỗi và/hoặc thay đổi.
Lưu trữ mỗi dòng trong một đối tượng lớp và sau đó xác định các trình so sánh khác nhau cho danh sách đối tượng lớp đó. Sử dụng điều này như một refenrece http://stackoverflow.com/questions/5245093/using-comparator-to-make-custom-sort – StackFlowed
cách sắp xếp hợp nhất? O (nlogn) –