0

I have date in this format:

Key        Value 
13:00:08 : 3
13:00:08 : 2
13:00:08 : 2
13:00:06 : 2
13:00:08 : 2
13:00:09 : 1
13:00:07 : 2
13:00:09 : 3

I convert the timestamp to seconds. Then based on the timestamp, I have to sort the data.

I tried using TreeMap but it removes duplicates. I tried HashMap but it removes the duplicates. MultiMap will not work here.

Code which I tried was :

Map<Integer, Integer> map = new TreeMap<Integer, Integer>(tmap);
        System.out.println("After Sorting:");
        Set set2 = map.entrySet();
        Iterator iterator2 = set2.iterator();
        while(iterator2.hasNext()) {
            Map.Entry me2 = (Map.Entry)iterator2.next();
            System.out.print(me2.getKey() + ": ");
            System.out.println(me2.getValue());
        }

How can I proceed with the sorting?

James Z
  • 12,209
  • 10
  • 24
  • 44
LearningToCode
  • 392
  • 5
  • 18
  • 1
    First of all, don't use raw types – Lino Jul 26 '18 at 15:18
  • Where does the data come from? How are you filling up the map? – Mureinik Jul 26 '18 at 15:19
  • Data comes from a listener which listens to the messages and writes it to a file. I am just filling the map by reading the file where messages are written after being listened. – LearningToCode Jul 26 '18 at 15:21
  • 1
    Out of the box java maps do not accept duplicate keys. Since both your keys and values have duplicates, you may want to use a custom class to hold the key value, define (in-)equality by both key and value, define comparability by timestamp comparison, and add instances of your class with the keys / values to a list, which you can then sort through the `Collections` utility method. – Mena Jul 26 '18 at 15:21
  • Your code is showing how you are printing a `Collection` but not how you are population it. Since you mention duplicated value, from the beginning, you can remove `Map` and `Set`. There is a [`MultiMap`](https://google.github.io/guava/releases/21.0/api/docs/com/google/common/collect/Multimap.html) in guava that could help but I never tried and never had to sort it. (EDIT : well there is a [SortedSetMultimap](https://google.github.io/guava/releases/21.0/api/docs/com/google/common/collect/SortedSetMultimap.html) interface so it should be possible) – AxelH Jul 26 '18 at 15:37
  • 1
    Possible duplicate of [Having a Multimap sorted on keys only in Java](https://stackoverflow.com/questions/5501468/having-a-multimap-sorted-on-keys-only-in-java) – AxelH Jul 26 '18 at 15:39
  • @AxelH Please refer to the marked answer. There is no reason for downvoting a question. – LearningToCode Jul 27 '18 at 13:31
  • I didn't... I just gave you a solution to use a `Map` with duplicated key. – AxelH Jul 27 '18 at 13:33

2 Answers2

3

Sounds like you just want a list.

Encapsulate the time and the value in an object, and process a list of these objects. You can then sort the list by time.

public class TimeValue {
    LocalTime time;
    int value;

    public TimeValue(LocalTime time, int value) {
        this.time = time;
        this.value = value;
    }

    public LocalTime getTime() {
        return time;
    }

    public static void main(String[] args) {
        List<TimeValue> timeValues = new ArrayList<>();
        timeValues.add(new TimeValue(LocalTime.of(13, 0, 8), 3));
        timeValues.add(new TimeValue(LocalTime.of(13, 0, 8), 2));
        timeValues.add(new TimeValue(LocalTime.of(13, 0, 8), 2));
        timeValues.add(new TimeValue(LocalTime.of(13, 0, 6), 2));
        timeValues.add(new TimeValue(LocalTime.of(13, 0, 8), 2));
        timeValues.add(new TimeValue(LocalTime.of(13, 0, 9), 1));
        timeValues.add(new TimeValue(LocalTime.of(13, 0, 7), 2));
        timeValues.add(new TimeValue(LocalTime.of(13, 0, 9), 3));

        timeValues.sort(Comparator.comparing(TimeValue::getTime));

        System.out.println(timeValues);
    }

    @Override
    public String toString() {
        return this.time + ": " + this.value;
    }
}

The reason why a List is preferable to a Map is that in your case the time is not unique; it can therefore not be used as a key.

Alex M
  • 885
  • 9
  • 12
1

So for the sample you posted, the actual problem is creating the tmap in your code sample. That's pretty much just parsing the data.

Map<LocalTime, List<Integer>> result = new TreeMap<>();
try (Scanner fileScanner = new Scanner(yourFile)) {
    while (fileScanner.hasNext()) {
        try (Scanner lineScanner = new lineScanner(fileScanner.nextLine())) {
            LocalTime time = DateTimeFormatter.ISO_LOCAL_TIME.parse(lineScanner.next());
            // skip the ":"
            lineScanner.next();
            int value = lineScanner.nextInt();
            // use the list for this time or create a new one if none is present
            List<Integer> valueList = result.computeIfAbsent(time, d -> new ArrayList<>());
            valueList.add(value);
        }
    }
}
daniu
  • 14,137
  • 4
  • 32
  • 53