Example #1
  * Executes the given consumer for each tracked object in parallel.
  * @param consumer the consumer
 public void forEachTrackedObject(BiConsumer<Client, Position> consumer) {
   requireNonNull(consumer, "consumer is null");
       (t, pt) -> {
         // pt.time is from the first time we encountered the position.
         // We might have gotten messages with the position but different timestamps
         // To avoid confusion we do not export the timestamp out
         consumer.accept(t, Position.create(pt.getLatitude(), pt.getLongitude()));
Example #2
  * Returns a map of tracked objects with their current position.
  * @return a map of tracked objects with their current position
 public Map<Client, Position> getTrackedObjects() {
   // We could return trackedObjects directly. But we do not want to return PositionTime objects
   // because the time is not the time from the latest report. But the first time with the current
   // position.
   // Which would be easily to mistake for users.
   HashMap<Client, Position> result = new HashMap<>();
   for (Map.Entry<Client, PositionTime> e : trackedObjects.entrySet()) {
         e.getKey(), Position.create(e.getValue().getLatitude(), e.getValue().getLongitude()));
   return result;