3

I have a class

public class SMS 
{
    public String addr;
    public String body;
    public String type;
    public String timestamp;
}

Now I have made an arrayList of objects

ArrayList<SMS> temp = new ArrayList<SMS>();

I have added the values. Now I want to sort the arrayList with respect to the timestamp.

How do I sort the arrayList in ascending/descending order with respect to the timestamp?

5
  • What is the format of timestamp? Commented Apr 13, 2014 at 6:12
  • Its a string e.g timestamp="1033123131"; Commented Apr 13, 2014 at 6:14
  • Is there a reason why you are storing it as String? Wouldn't long type be better? Commented Apr 13, 2014 at 6:17
  • I would convert it to long that is not the problem. The problem is how do I sort it then? Commented Apr 13, 2014 at 6:20
  • possible duplicate of Sort ArrayList of custom Objects by property Commented Apr 25, 2014 at 20:33

4 Answers 4

8
Collections.sort(temp);

will sort a collection of Comparable objects, so class SMS has to implement Comparable<SMS> :

public class SMS implementes Comparable<SMS>
{
    public String addr;
    public String body;
    public String type;
    public String timestamp;

    @Override
    public int compareTo(SMS other) {
       //for instance
       return addr.compareTo( other.addr );
    }
}

It is usually a good practice, when implementing Comparable to also implement equals() and hashcode() so that equality between objects is consistent with their comparison. Also, you should add some protection against null values :

public class SMS implements Comparable<SMS>
{
    public String addr;
    public String body;
    public String type;
    public String timestamp;

    @Override
    public int compareTo(SMS other) {
       //for instance
       if( addr == null ) {
           return Integer.MAX_VALUE;
       }
       return addr.compareTo( other.addr );
    }

    @Override
    public boolean equals(Object other) {
       //for instance
       if( other instanceof SMS ) {
          if( addr == null && ((SMS) other) != null ) {
              return false;
          }
          return addr.equals(((SMS) other).addr);
       } else {
          return false;
       }
       return addr.compareTo( other.addr );
    }

    @Override
    public int hashcode() {
       //for instance
       if( addr == null ) {
           return 0;
       }
       return addr.hashcode();
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Is that the correct answer ? A few more upvotes would get me enlightened : stackoverflow.com/help/badges/19/enlightened
5

To compare Strings containing timestamps you need to first parse them to long Long.parseLong(timestamp) and then compare numeric value using Long.compare(x,y).

So try maybe with Collections.sort(yorList, yourOwnComparator) like

Collections.sort(temp, new Comparator<SMS>() {
    @Override
    public int compare(SMS o1, SMS o2) {
        return Long.compare(Long.parseLong(o1.timestamp), 
                            Long.parseLong(o2.timestamp));
    }
});

If you can change type of timestamp to long this code could look like

Collections.sort(temp, new Comparator<SMS>() {
    @Override
    public int compare(SMS o1, SMS o2) {
        return Long.compare(o1.timestamp, o2.timestamp);
    }
});

In Java8 you can even use lambdas to shorten code even more

Collections.sort(temp, (SMS o1, SMS o2) -> Long.compare(o1.timestamp, o2.timestamp));

or even

Collections.sort(temp, (o1,  o2) -> Long.compare(o1.timestamp, o2.timestamp));

2 Comments

That's a good alternative, with some protection against o1 and/or o2 being null.
@Snicolas True. To avoid NPE OP would have to make sure that timestamp is not null. But I think that letting timestamp be null may be bigger issue so throwing NPE in this case would be informing that somewhere (earlier) in code exists a way/bug which lets timestamp be nulls. Decision where to handle it belongs to OP.
0

Use Comparable (see example here), it should be something like this:

public class SMS implements Comparable<SMS>{

    ....

    public int compareTo(SMS compareSms) { 
        return this.timestamp.compareTo(compareSms.timestamp);
    }
}

Comments

0

This is the general testing code:

ArrayList<SMS> temp = new ArrayList<SMS>();

// testing values
SMS a = new SMS();
a.setTime("a time");
SMS b = new SMS();
b.setTime("b time");
SMS c = new SMS();
c.setTime("c time");
temp.add(a);
temp.add(b);
temp.add(c);

// descending sort
Collections.sort(temp, new Comparator<SMS>() {
    public int compare(SMS text1, SMS text2) {
        // compare timestamps from the SMSs
        return text2.getTime().compareTo(text1.getTime());
    }
});

// print it out to test
for (SMS sms : temp) {
    System.out.println(sms.getTime());
}

If I want to change it from ascending to descending, I would simply need to switch the way I compare the text messages. Look at this:

return text2.getTime().compareTo(text1.getTime()); // descending
return text1.getTime().compareTo(text2.getTime()); // ascending

Note: I assume that getTime() returns the timestamp of the text message, and you need to add this import statement to your class: import java.util.Collections; or just import java.util.*;

To use the getTime() and setTime(String timestamp) methods, your class may look like this:

public class SMS 
{
    public String addr;
    public String body;
    public String type;
    public String timestamp;

    public void setTime(String timestamp) {
        this.timestamp = timestamp;
    }

    public String getTime() {
        return timestamp;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.