0

I have an arraylist created from an iteration

ArrayList<String> ulpList = new ArrayList<String>();
String record = id + "," + lp.getTime() + "," + lp.getLatitude() + "," + lp.getLongtitude() + "," + lp.getPoint() + ", " + lp.getDistance();
ulpList.add(record);

There will be many instances of the same id, with different times, latitudes, longitudes, points and distances. Thus I want to break the arraylist ulplist into various sublists. Then, I want to order/sort these sublists by time. After I have sorted the sublists by time, I want to perform some calculations and then join them back and output the result into a .csv file. I just need to know how to break up the arraylist into these sublists that I want (which will be temporary) then how to sort them according to time, which is after the first , delimiter.

Sample output:

[[04ae46c177169feac5f697eexxxx,1418601075,1.375579,103.960797,null, 1000.0]]
[[04ae46c177169feac5f697eexxxx,1418602016,1.381164,103.966164,null, 1000.0]]
[[04ae46c177169feac5f697eexxxx,1418603148,1.381164,103.966164,null, 1000.0]]
[[04ae46c177169feac5f697eexxxx,1418601994,1.381164,103.966164,null, 1000.0]]
[[055ee328d4d297500e9a7f4cffe6xxxx,1418602721,1.313564,103.878443,null, 1000.0]]
[[055ee328d4d297500e9a7f4cffe6xxxx,1418602119,1.313564,103.878443,null, 1000.0]]
[[055ee328d4d297500e9a7f4cffe6xxxx,1418601901,1.313564,103.878443,null, 1000.0]]
[[055ee328d4d297500e9a7f4cffexxxx,1418600991,1.313564,103.878443,null, 1000.0]]
[[055ee328d4d297500e9a7f4cffe6xxxx,1418600132,1.313564,103.878443,null, 1000.0]]
[[00cd34bad39d19f8e2a335b444bxxxx,1418600273,1.345569,103.696973,null, 1000.0]]
[[04036dd2f45253bc9c24810f8e3exxxx,1418603285,1.301047,103.853357,null, 1000.0]]
user3763216
  • 489
  • 2
  • 10
  • 29
  • "break up the arraylist into these sublists" - by which criteria do you want to divide the full list into sublists? – TDG Sep 28 '15 at 09:02
  • Please refer http://stackoverflow.com/questions/2784514/sort-arraylist-of-custom-objects-by-property – iprashant Sep 28 '15 at 09:02
  • @TDG the arraylist will have repeated ids, so i want to break up the lists by those with the same ids! so like one id, one list. – user3763216 Sep 28 '15 at 09:03
  • @uniquephase it is not exactly an object as `id` is a parameter i have passed in. i want to split based on id, and then sort using the attribute at position [1] of the string, using the delimiter `,`. and i kinda mainly want to know how to split before i sort. – user3763216 Sep 28 '15 at 09:08
  • 1
    Why do you want to split the `List` into sublists? You only want to sort having multiple sorting parameters. – Flown Sep 28 '15 at 09:12
  • @Flown because after i have lists with the same id, that list will be sorted according to time, and then i want to perform some other calculations. so primarily i want to order by id first, then time. – user3763216 Sep 28 '15 at 09:15
  • Which time API you're using? `Date` or `LocalTime` or milliseconds? – Flown Sep 28 '15 at 09:17
  • @Flown unix timestamp//milliseconds – user3763216 Sep 28 '15 at 09:21

3 Answers3

1

You could use java 8 streams, for something like:

Map<String, List<String>> groups = ulpList.stream().collect(Collectors.groupingBy(e -> e.split(",")[0]));

ArrayList<List<String>> sorted = new ArrayList<>();
for (List<String> s : groups.values()) {
    sorted.add(s.stream().sorted((s1, s2) -> {
        long ts1 = Long.valueOf(s1.split(",")[1]);
        long ts2 = Long.valueOf(s2.split(",")[1]);
        return Long.compare(ts1, ts2);
    }).collect(Collectors.toList()));
}
// do calculations 
// ...

Of course you could change string to string[] to reduce number of splits, and write it a bit more efficient and elegant way, but I wanted to keep it simple

marekk
  • 237
  • 2
  • 11
  • hey i tried your method, all those with the same IDs seem to be grouped together, but the time stamps are still not in order? here's the sample output – user3763216 Sep 28 '15 at 09:40
  • 1
    I've run above code for your input but the output is as expected – marekk Sep 28 '15 at 10:05
0

you are first inserting and then splitting, why dont you create a map containing linked list. As you need id to be unique, so map can do this and rest of details will be stored in list. As far as sorting on the basis of time is required you can use comparator.

iprashant
  • 155
  • 1
  • 2
  • 11
  • i don't want the id to be unique, i just want to group the time, lat, long, point and distance by their ids, so one id will have multiple time, lat, long, point and distance. then from there then i will rearrange the attributes in each list according to their time and then perform calculations. on another note, i have about 70k records – user3763216 Sep 28 '15 at 09:25
  • 1
    dude you can do this using map of String to list. And using your custom comparator you can pick any id and sort all those records corresponding to that id on the basis of time. – iprashant Sep 28 '15 at 09:33
0

You should transform your List<String> into a Map<String, List<String[]>> for further processing. In the end you can join the lines again and write it to a CSV file.

Java 7

public Map<String, List<String[]>> groupAndSort(List<String> ulpList) {
    Map<String, List<String[]>> grouping = new TreeMap<>();
    for (String line : ulpList) {
        String[] split = line.split(",");
        List<String[]> value = grouping.get(split[0]);
        if (value == null) {
            value = new ArrayList<>();
            grouping.put(split[0], value);
        }
        value.add(split);
    }
    for (List<String[]> value : grouping.values()) {
        Collections.sort(value, new Comparator<String[]>() {
            @Override
            public int compare(String[] o1, String[] o2) {
                return Long.compare(Long.parseLong(o1[1]), Long.parseLong(o1[2]));
            }
        });
    }
    return grouping;
}

Java 8

public Map<String, List<String[]>> groupAndSort8(List<String> ulpList) {
    Map<String, List<String[]>> grouping = ulpList.stream().map(l -> l.split(","))
            .collect(Collectors.groupingBy(l -> l[0], TreeMap::new, Collectors.toList()));
    grouping.forEach((k, v) -> Collections.sort(v, Comparator.comparingLong(l -> Long.parseLong(l[1]))));
    return grouping;
}
Flown
  • 11,480
  • 3
  • 45
  • 62