简体   繁体   中英

Need suggestion for a suitable data structure

Day1
  Hour1
    Minute1 
​      Location1(i.e. lat,lon)
      Location2 
    Minute2 
  Hour2
  Hour3​ 
Day2 
  Hour1 
    Minute1
​    Minute2​
  Hour2​

​There are multiple users with user locations by timestamp (date:hour:min:sec). I need to stack all the user location data with time regardless of date (ie; only hour and min)

Eg: stack everyday location data into a 24 hour (24*60 mins) timeline.

I did this only for hours resolution using 24 Array Lists and check each timestamp's hour value and then using a switch statement assign each corresponding location value to one of the Array Lists.

When going into minutes resolution it is not practical to have 1440 (24*60) Array Lists. I am much grateful if you can suggest any efficient way to do this. I hope I made myself clear when explaining my problem.

Thanks in advance, Hasala

EDIT: Following is the code written to hours resolution.

//24 ArrayLists to store users with location according to hours of the day
ArrayList<Location> hour1 = new ArrayList<Location>();
ArrayList<Location> hour2 = new ArrayList<Location>();
ArrayList<Location> hour3 = new ArrayList<Location>();
ArrayList<Location> hour4 = new ArrayList<Location>();
ArrayList<Location> hour5 = new ArrayList<Location>();
ArrayList<Location> hour6 = new ArrayList<Location>();
ArrayList<Location> hour7 = new ArrayList<Location>();
ArrayList<Location> hour8 = new ArrayList<Location>();
ArrayList<Location> hour9 = new ArrayList<Location>();
ArrayList<Location> hour10 = new ArrayList<Location>();
ArrayList<Location> hour11 = new ArrayList<Location>();
ArrayList<Location> hour12 = new ArrayList<Location>();
ArrayList<Location> hour13 = new ArrayList<Location>();
ArrayList<Location> hour14 = new ArrayList<Location>();
ArrayList<Location> hour15 = new ArrayList<Location>();
ArrayList<Location> hour16 = new ArrayList<Location>();
ArrayList<Location> hour17 = new ArrayList<Location>();
ArrayList<Location> hour18 = new ArrayList<Location>();
ArrayList<Location> hour19 = new ArrayList<Location>();
ArrayList<Location> hour20 = new ArrayList<Location>();
ArrayList<Location> hour21 = new ArrayList<Location>();
ArrayList<Location> hour22 = new ArrayList<Location>();
ArrayList<Location> hour23 = new ArrayList<Location>();
ArrayList<Location> hour24 = new ArrayList<Location>();
//

//
void processToHours(){  
  for (int p=0;p<timeStamps.size();p++){
    String time = timeStamps.get(p);
    Location userLoc = new Location(Double.parseDouble(lat.get(p)),Double.parseDouble(lon.get(p)));
    int hour = convertTime(time);
        //
        switch (hour) {
            case 0:  hour1.add(userLoc);
                     break;
            case 1:  hour2.add(userLoc);
                     break;
            case 2:  hour3.add(userLoc);
                     break;
            case 3:  hour4.add(userLoc);
                     break;
            case 4:  hour5.add(userLoc);
                     break;
            case 5:  hour6.add(userLoc);
                     break;
            case 6:  hour7.add(userLoc);
                     break;
            case 7:  hour8.add(userLoc);
                     break;
            case 8:  hour9.add(userLoc);
                     break;
            case 9:  hour10.add(userLoc);
                     break;
            case 10: hour11.add(userLoc);
                     break;
            case 11: hour12.add(userLoc);
                     break;
            case 12: hour13.add(userLoc);
                     break;
            case 13: hour14.add(userLoc);
                     break;         
            case 14: hour15.add(userLoc);
                     break;
            case 15: hour16.add(userLoc);
                     break;
            case 16: hour17.add(userLoc);
                     break;
            case 17: hour18.add(userLoc);
                     break;
            case 18: hour19.add(userLoc);
                     break;
            case 19: hour20.add(userLoc);
                     break;
            case 20: hour21.add(userLoc);
                     break;
            case 21: hour22.add(userLoc);
                     break;
            case 22: hour23.add(userLoc);
                     break;
            case 23: hour24.add(userLoc);
                     break;
            default: println("Invalid Time");
                     break;
        }
        //
  }
}
//

I would use Json string to hold the data, then when I need data I would parse the string and extract data accordingly.

For example, I want data for day 1, hour 1, minute 1...then... write the function :

List<String> GetLocation(String jsonStr, String dayNumber, String hrNumber, String miNumber){
List<String> locationList = new ArrayList<String>();
//extract data by parsing json
//add extracted location in list
return locationList;
}

Note : The drawback of this method is you have to parse JSON String every time you need the specific data.

OR you can use this in a best way according to nature of your data usage.

When you start writing out list1, list2, etc, etc. You should consider a list contain all of your other lists. For example.

class Day{
    List<Hour> hours;
}
class Hour{
    List<Minute> minutes;
}
class Minute{
    List<Location> locations;
}

I also like the idea of using a Map instead of a list so that you don't have to populate the list with all possible hours/minutes, eg.

class Day{
    Map<Integer, Hour> hours = new HashMap<>();

    public void addLocation(int hour, int minute, Location location){
        if(!hours.containsKey(hour)){
            hours.put(hour, new Hour());
        }
        hours.get(hour).addLocation(minute, location);
    }
    public Hour getHour(int hour){
        return hours.get(hour);
    }
}

class Hour{
    Map<Integer, Minute> minutes = new HashMap<>();
    public void addLocation(int minute, Location location){
        if(!minutes.containsKey(minute)){
            minutes.put(minute, new Minute());
        }
        minutes.get(minute).addLocation(location);
    }
}

class Minute{
    List<Location> locations = new ArrayList<>();
    public void addLocation(Location location){
        locations.add(location);
    }
}

public class LocationManager{
    Map<Integer, Day> days = new HashMap<>();
    public void addLocation(int day, int hour, int minute, Location location){
        if(!days.containsKey(day)){
            days.put(day, new Day());
        }
        days.get(day).addLocation(hour, minute, location);
    }
}

Sounds to me you need your own, modified, implemenration of Trie ( https://en.m.wikipedia.org/wiki/Trie ) where the keys in th trie are numbers, where each level corresponds to either hour, minute or second, whereas the value is the location.

I'm on my mobile phone right now, but take a look at Princeton's algorithms (not sure which one, 1 or 2) and their implementation of key-value tries.

That can be your backing structure, but for the sake of good programming principles, you still need to encapsulate it so it has a above API for all the reasons out there :).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM