Q:

Get minimum and maximum from a list of objects

I have this class
class TimeSpentStats{
  int manId;
  String sessionId;
  int userId;
  Long timeStamp;
}

I have a List and I want to get the minimum timestamp and maximum
 from the list for each (manId, sessionId, userId)
So for example, I have:
manId sessionId userId timeStamp
1      01F      5          1000
1      01F      5          1005
3      6Y       3           7
3      6Y       3           16

I need for  (1   01F 5) -> min = 1000 , max = 1005
   and for (3      6Y  3 ) - > min = 7 , max = 16
I need to add maybe 2 attributes in the same class?
Any ideas if I can do this? Thank you

A:

If you have a List of TimeSpentStatus called list, the following algorithm should do what you want it to do.
HashMap<String, Pair> statsList = new HashMap<String, Pair>();
for(TimeSpentStats stats : list){
    // Constructs the combination of IDs that is used as the key to a Pair object
    String statsStr = stats.manId + " " + stats.sessionId + " " + stats.userId;
    if(statsList.containsKey(statsStr)){
        // Update min and/or max time for the current combination as necessary
        statsList.get(statsStr).minTime = Math.min(statsList.get(statsStr).minTime, stats.timeStamp);
        statsList.get(statsStr).maxTime = Math.max(statsList.get(statsStr).maxTime, stats.timeStamp);
    }else{
        // Construct a new Pair for the ID combination and add max and min times
        Pair p = new Pair();
        p.maxTime = stats.timeStamp;
        p.minTime = stats.timeStamp;
        // Adds the new combination to the HashMap, which can now be updated in the if-statement
        statsList.put(statsStr, p);
    }
}

statsList will now contain the max and min times for each combination with (userID + " " + manID + " " + sessionID) as the keys. You will then be able to get the Pair object for a specific combination by using statsList.get(userId + " " + manId + " " + sessionId) (as long as it exists of course).
Here is the Pair class
class Pair{
    public long minTime;
    public long maxTime;
}

A:

public class Main
{
    public static void main( String[] args )
    {
        Map< TimeSpentStats, MinMax > hashMap = new HashMap< TimeSpentStats, MinMax >();
        addToMap( hashMap, new TimeSpentStats( 1, "01F", 5, 1000L ) );
        addToMap( hashMap, new TimeSpentStats( 1, "01F", 5, 1005L ) );
        addToMap( hashMap, new TimeSpentStats( 3, "6Y", 3, 7L ) );
        addToMap( hashMap, new TimeSpentStats( 3, "6Y", 3, 16L ) );

        for ( Map.Entry< TimeSpentStats, MinMax > entry : hashMap.entrySet() )
        {
            TimeSpentStats timeSpentStats = entry.getKey();
            MinMax minMax = entry.getValue();
            System.out.println( timeSpentStats.getManId() + "\t" + timeSpentStats.getSessionId() + "\t" + timeSpentStats.getUserId() + "\tMin Time Stamp :" + minMax.getMin() + "\tMax Time Stamp :" + minMax.getMax() );
        }
    }

    private static void addToMap( Map< TimeSpentStats, MinMax > hashMap, TimeSpentStats timeSpentStats )
    {
        MinMax timeStampMinMax = hashMap.get( timeSpentStats );
        if ( timeStampMinMax != null )
            timeStampMinMax.updateValues( timeSpentStats.getTimeStamp() );
        else
            hashMap.put( timeSpentStats, new MinMax( timeSpentStats.getTimeStamp() ) );
    }
}

class MinMax
{
    private Long min;
    private Long max;

    MinMax( Long timeStamp )
    {
        this.min = timeStamp;
        this.max = timeStamp;
    }

    public Long getMin()
    {
        return min;
    }

    public Long getMax()
    {
        return max;
    }

    public boolean updateValues( Long timeStamp )
    {
        if ( timeStamp < this.min )
        {
            this.min = timeStamp;
            return true;
        }
        else if ( timeStamp > this.max )
        {
            this.max = timeStamp;
            return true;
        }

        return false;
    }
}

class TimeSpentStats
{
    private final int manId;
    private final String sessionId;
    private final int userId;
    private final Long timeStamp;

    public TimeSpentStats( int manId, String sessionId, int userId, Long timeStamp )
    {
        this.manId = manId;
        this.sessionId = sessionId;
        this.userId = userId;
        this.timeStamp = timeStamp;
    }

    public int getManId()
    {
        return manId;
    }

    public String getSessionId()
    {
        return sessionId;
    }

    public int getUserId()
    {
        return userId;
    }

    public Long getTimeStamp()
    {
        return timeStamp;
    }

    @Override
    public boolean equals( Object obj )
    {
        if ( obj instanceof TimeSpentStats )
        {
            TimeSpentStats timeSpentStats = (TimeSpentStats)obj;
            return this.manId == timeSpentStats.manId && this.sessionId.equals(timeSpentStats.sessionId) && this.userId == timeSpentStats.userId;
        }
        return false;
    }

    @Override
    public int hashCode()
    {
        return sessionId.hashCode();
    }
}

Edit : a small bug is fixed. Here I had forgot to use .equals(), as the sessionId you have mentioned is of String type.

