Comp Sci How Can I Ensure Messages in Java ArrayList Are Sorted by Time Descending Order?

  • Thread starter Thread starter blah45
  • Start date Start date
  • Tags Tags
    Hard Java
AI Thread Summary
To ensure messages in a Java ArrayList are sorted by time in descending order, the add method in the MessageList class must be implemented correctly. When adding a new message, if the list is empty, the message can be added directly. If the list contains messages, a loop should compare the timeReceived of the new message with existing messages to find the correct insertion point, using the add(index, element) method to maintain order. It is suggested that a linked list may be more efficient for frequent insertions, although an ArrayList can suffice for this task. The erase method can be simplified by using the clear() method instead of manually removing each element.
  • #51


I just used a for loop and added delay that way and it worked =D
 
Physics news on Phys.org
  • #52


I'll do some other testing and let you know Thanks for all the help, thanks so much, I really do appreciate it.
 
  • #53


Cathal Cronin said:
Whe I put that in I get an erroe saying " unreported exception java.lang.InterruptedException ; must be caught or declared to be thrown

Best you know how to handle that, and why it's happening. Trust me, it'll come up again.

Look at the Thread.sleep method's signature in the Java API docs:
Code:
public static void sleep(long millis)
                  throws InterruptedException
So it declares that it may throw that exception and that it must be handled (and tells you the two ways to handle it).

As with any exception, it may be caught. So you can put a try/catch block around the calls to Thread.sleep. Just wrap the part with sleep calls with something like this:
Code:
try {
    // Bunch of code
    Thread.sleep(250);
    // etc ...
} catch (InterruptedException e) {
    // Handle the exception
    e.printStackTrace();
}

That makes the compiler happy. Having a throws clause in a method signature forces the programmer using it to handle the exception.

But you can also pass the buck and make any method that calls yours (the one with the sleeps in it) handle it. It will needs to be handled somewhere down the line, but sometimes it's appropriate to let a calling method handle it. In which case you just add a throws clause to your own method. For example:
Code:
public void tester() throws InterruptedException
{
    Thread.sleep(250);
    // ... etc ...
}
Now any method calling tester() will need to handle catching the exception (or passing the buck with another throws).

And thanks to Mark for pointing out it's static. Been a few years since I've used threads in Java and somehow had the idea in my head that it had to be used in a Thread/Runnable class. Which is not the case, since it's static and we're just running in the main thread.

Well, hope that clears it up. It's quite common that an API method will have a throws clause, so you'll need to know it soon enough.
 
  • #54


Cathal Cronin said:
I'll do some other testing and let you know Thanks for all the help, thanks so much, I really do appreciate it.
You're welcome. I know that both Grep and I enjoy being able to help out.
 
  • #55


I'm back again, it works but just wondering do I have to do the Thread.sleep(n) thing or is this(i.e what I have at the moment) okay...

Code:
public class messageDriver
{
    public static void main(String args[])
    {
        MessageList Inbox = new MessageList() ;
        int i = 0;        
        Message msg1 = new Message("123456","Hi") ;
        
        for(i = 0 ; i < 10000000 ; i++);
        Message msg2 = new Message("123456","Hey, how are you") ;
        
        for(i = 0 ; i < 10000000 ; i++);
        Message msg3 = new Message("123456","grand, you?") ;
        
        for(i = 0 ; i < 10000000 ; i++);
         Message msg4 = new Message("123456","I'm okay,gotta go now, talk later!") ;
       
        for(i = 0 ; i < 10000000 ; i++);
        Message msg5 = new Message("123456","ok bye") ;
        
        for(i = 0 ; i < 10000000 ; i++);
        Message msg6 = new Message("123456","bye bye") ;
        
        for(i = 0 ; i < 10000000 ; i++);

        Inbox.addMsg(msg5) ;
        Inbox.addMsg(msg1) ;
        Inbox.addMsg(msg3) ;
        Inbox.addMsg(msg6) ;
        Inbox.addMsg(msg2) ;        
        Inbox.addMsg(msg4) ;
        
        Inbox.display() ;

    }
}
 
  • #56


Cathal Cronin said:
I'm back again, it works but just wondering do I have to do the Thread.sleep(n) thing or is this(i.e what I have at the moment) okay...

Like I said earlier, the for loop thing works, but it's kind of cheesy. :biggrin:

Sleep is fine. Or also appropriate would be what I proposed earlier with the while loop. it just waits until it sees the timer has incremented and is now different than the one from the previous message. Then it exits the while loop and goes on to the next message.

If you look back a bit you can find it. But yeah, sleep is also totally appropriate. I, personally, would be a bit embarrassed to hand in a program using for loops for delays like that. I'd only use it for a quick temporary test. But it's up to you.

And thanks. Like Mark said, glad to help.
 
  • #57


I was looking up the API for the thread but I don't exactly know how to use it in the driver, does it really matter apart from being "cheesy"?
 
  • #58


Cathal Cronin said:
I was looking up the API for the thread but I don't exactly know how to use it in the driver, does it really matter apart from being "cheesy"?

Well, it could be an issue, in theory. Maybe your computer in the future will be fast enough so that it does 1,000,000 iterations before the clock can update. Who knows. Probably not an issue, but it's so easy to do it better.

Here, I'll show you how I might do it more cleanly because I think you can learn a lot from seeing it. I'll use the while loop method I mentioned because it gets to the core of the issue. The clock must update between messages. And may as well use loops to arrange a sequence of messages.

Code:
    public static void main(String args[])
    {
        MessageList inbox = new MessageList() ;
        int numMessages = 6;
        int testOrder[] = {4, 0, 2, 5, 1, 3};
        Message messages[] = new Message[numMessages];

        // Create the messages, making sure system clock changes before next message
        for (int i = 0; i < numMessages; i++)
        {
            messages[i] = new Message(Integer.toString(i), "Message " + i);

            long messageTime = messages[i].getTimePc();
            while (System.nanoTime() == messageTime);
        }

        // Add messages to list in the order specified by the testOrder[] array
        for (int i = 0; i < numMessages; i++)
        {
            inbox.add(messages[testOrder[i]]);
        }

        inbox.display();
    }

I'd also add some code to test it and tell me if it's working ok or not (messages in expected order, and the right number of messages). But I suppose no need if it wasn't asked for.

Anyways, hope you found that enlightening.
 
Last edited:
  • #59


I wanted to add that there's a simpler way I can think of to write the add method. I wrote nicely commented code that does it, but it wouldn't be proper to just post it, IMO.

However, I'll post the comments for the three logic branches in my if/else-if/else block. It'll still be up to you to turn it into nice code to fix what you have now. I hope it will help at least untangle the logic in your mind.

1. Always keeping in mind that the messages are ordered from newest to oldest in the list, first, I did this:
// Is list empty? Then just add.

2. If the list wasn't empty, I checked another special case:
// Is new message older than oldest message at end of list?
// Then just append to end of list (early part)

3. Otherwise, I had a simple case of iterating over *all* the elements one by one from the start with this logic:
// Otherwise we will need to find the element we are newer than
// starting from the beginning of the list with the newest times.
// If we're greater than it, then we've found our position and
// insert ourselves in front of the element. If there was a
// newer element in the list, we would have gotten to it already
// earlier in the list (where times are newer).
(EDIT: I believe the comparison on this last case should be greater than OR EQUAL TO. Keep that in mind.)

So you see that handles all the possibilities as far as I can see. I'm tired and might have made a mistake, but I present this logic to you for your consideration. Seems to work and makes good logical sense, I think.
 
Last edited:

Similar threads

Replies
7
Views
2K
Replies
12
Views
2K
Replies
1
Views
2K
Replies
1
Views
1K
Replies
2
Views
4K
Replies
2
Views
1K
Replies
6
Views
3K
Replies
1
Views
2K
Back
Top