Carlton Jr. Carlton Jr. - 2 months ago 6
Java Question

get objects from a list in LIFO order? (Last-In-First-Out) (Beginner)

(Please, bear in mind that this is a beginners problem)

I have two classes;

MailItem
and
MailServer
. I have a testing class, where I make and send MailItems to my MailServer. I sent to MailItems to one specific user, and I expect to retreive these in LIFO-order(Last-In-First-Out), so the lastest to be sent have to be the first I recieve.

Here are my classes.

MailItem class:

public class MailItem
{
private String from;
private String to;
private String message;
private String subject;

public MailItem(String from, String to, String message, String subject)
{
this.from = from;
this.to = to;
this.message = message;
this.subject = subject;
}

public String getFrom()
{
return from;
}

public String getTo()
{
return to;
}

public String getSubject(){
return subject;
}

public String getMessage()
{
return message;
}

public void print()
{
System.out.println("From: " + from);
System.out.println("To: " + to);
System.out.println("Message: " + message);
System.out.println("Subject: " + subject);
}
}


MailServer class:

public class MailServer
{
private List<MailItem> items;
private HashMap<String, List<MailItem>> hashmap;

public int howManyMessages(){
return items.size();
}

public int howManyUsers(){
return hashmap.size();
}

public MailServer()
{
items = new LinkedList<MailItem>();
hashmap = new HashMap<String, List<MailItem>>();
}

public int howManyMailItems(String who)
{
int count = 0;
for(MailItem item : items) {
if(item.getTo().equals(who)) {
count++;
}
}
return count;
}

public MailItem getNextMailItem(String who)
{
Iterator<MailItem> it = items.iterator();
while(it.hasNext()) {
MailItem item = it.next();
if(item.getTo().equals(who)) {
it.remove();
return item;
}
}
return null;
}

public void post(MailItem item)
{
if(!isEmpty(item)){
items.add(item);
}
}

private boolean isEmpty(MailItem mail){
if(mail.getFrom() == "" || mail.getTo() == ""){
return true;
}
return false;
}

public int createMailbox(String user){
if(hashmap.containsKey(user)){
return 0;
}
List<MailItem> mil = new ArrayList<MailItem>();
hashmap.put(user, mil);
return 1;
}

public int createMailbox(String[] users){
int createdBoxes = 0;
for(String user: users){
int created = createMailbox(user);
if(created == 1){
createdBoxes++;
}
}
return createdBoxes;
}

private List<MailItem> getMailbox(String who){
if(hashmap.containsKey(who)){
List<MailItem> ls = hashmap.get(who);
return ls;
}else{
return null;
}
}
}


Here is how my test look like:

@Test
public void testReceiveOrder(){
mailServer.post(mess1User1to2);
mailServer.post(mess2User1to2);
assertEquals(mess2User1to2,mailServer.getNextMailItem("user2"));
}


When I run this test, I retrieve these emails in a FIFO(First-In-First-Out) manner. Instead of retrieving the mail called mess2User1to2, I get mess1User1to2. I tried using LinkedList to retrieve them in LIFO, but It did not work for me. What did I do wrong?

Answer

Your post method adds the item to the end of the list and your getNextMailItem method starts searching for the item in the front of the list. Therefore you get FIFO (=queue) behaviour.

To change this either start searching at the end of the list:

public MailItem getNextMailItem(String who) {
    ListIterator<MailItem> it = items.listIterator(items.size());
    while(it.hasPrevious()) {
        MailItem item = it.previous();
        if(item.getTo().equals(who)) {
            it.remove();
            return item;
        }
    }
    return null;
}

Alternatively you could instead add the items to the front of the list, but I haven't checked, if this breaks any other methods:

private LinkedList<MailItem> items;

public void post(MailItem item) {
    if(!isEmpty(item)){
        items.addFirst(item);
    }
}
Comments