Sort an array of Java strings by multiple numbers

I have a list of data in a txt file like

Date,Lat,Lon,Depth,Mag 20000101,34.6920,-116.3550,12.30,1.21 20000101,34.4420,-116.2280,7.32,1.01 20000101,37.4172,-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,59.7753,-152.2192,86.34,1.48 20000101,34.5230,-116.2410,11.63,1.61 20000101,59.5369,-153.1360,100.15,1.62 20000101,44.7357,-110.7932,4.96,2.20 20000101,34.6320,-116.2950,9.00,1.73 20000101,44.7370,-110.7938,5.32,1.75 20000101,35.7040,-117.6320,4.15,1.45 20000101,41.9270,20.5430,10.00,4.80 

my job is to sort this data by each criterion ex) sort by date, latitude and longitude

I tried a similar bubble

 if ( Double.parseDouble(a[0].split(",")[1]) < Double.parseDouble(a[1].split(",")[1])) 

it works but takes too long

theres 40000 data in txt file

Is there an alternative way to sort this data?

+5
source share
2 answers

I probably ruin the students homework assignment, but here goes ...

As suggested in the question, the natural way in Java is to create a class to represent your data. Then run Comparator , which will be passed to the Collections.sort utility.

On my MacBook Pro 2.3 GHz Intel Core i7 running on a Parallels virtual machine with Java 8, a 42,000-element dataset takes 45 to 90 milliseconds to sort.

I modified your sample data to be more interesting by entering several different dates and repeating latitudes.

 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 

My GeoReading class is for representing data.

 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 + '}'; } } 

Here is a comparator implementation.

 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 ); } } 

The main code.

 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 ); } 

In the real world, I would add a protective programming code to check incoming data. Data from external sources is always defective and / or changing.

0
source

Try sorting a merge . Merge sort has the worst performance O (n log n). The shortest bubble sorting time is O (n ^ 2).

+5
source

Source: https://habr.com/ru/post/1205379/


All Articles