Update properties of a linked list/vector

I've got objects (Ranks) that are being added to a list as another list is looped through.

Each of these objects has an "up" and a "down" property, which need to be set to the following and previous element, respectively. If the element is at the top of the list, the "up" property should point to itself, likewise for the bottom element.

I'm using a Vector (java.util.Vector) so I can use indices to find the following and previous elements. Here is the adding process, with manipulating up/down:

public void addToRanksInOrderWithUpDown(Rank r) {
    ranksInOrder.addElement(r);
    if (ranksInOrder.size() != 1) {
        Rank ru, rd;
        try {
            ru = ranksInOrder.elementAt(ranksInOrder.indexOf(r)+1);
        } catch (ArrayIndexOutOfBoundsException e) {
            ru = r;
        }
        try {
            rd = ranksInOrder.elementAt(ranksInOrder.indexOf(r)-1);
        } catch (ArrayIndexOutOfBoundsException e) {
            rd = r;
        }
        r.setUp(ru);
        r.setDown(rd);
        ru.setDown(r);
        rd.setUp(r);
    }
}

r being an instance of a passed Rank. Here is the loop:

if (g.getRanksInOrder().size() == 1) {
    g.addToRanksInOrder(currentRank);
} else {
    g.addToRanksInOrderWithUpDown(currentRank);
}

addToRanksInOrder simply does the first step of addToRanksInOrderWithUpDown, ranksInOrder.addElement(r);.

Unfortunately, "up" and "down" often end up being Null or the wrong thing. What is a better way to go about this? Can I fix my code, or does it need to be scrapped?

Edit: sorry, but none of the answers actually work. The problem remains as before, with various ups/downs remaining null or the wrong thing.


Here's an SSCCE:

public class Rank {
    private Rank up;
    private Rank down;
    private String name;
    public Rank getUp() {
        return up;
    }
    public Rank getDown() {
        return down;
    }
    public Rank getName() {
        return name;
    }
    public void setUp(Rank r) {
        up = r;
    }
    public void setDown(Rank r) {
        down = r;
    }
    public Rank(String s) {
        name = s;
    }
}

public class Ranker {
    private Set<Rank> ranks = new HashSet<Rank>();
    private Vector<Rank> ranksInOrder = new Vector<Rank>(); 
    public Vector<Rank> sort() {
        for (Rank r : ranks) {
            if (ranksInOrder.size == 1) {
                addToRanksInOrder(r);
            } else {
                addToRanksInOrderWithUpDown(r);
            }
        }
        return ranksInOrder;
    }
    private void addToRanksInOrderWithUpDown(Rank r) {
        ranksInOrder.addElement(r);
        if (ranksInOrder.size() != 1) {
            Rank ru, rd;
            try {
                ru = ranksInOrder.elementAt(ranksInOrder.indexOf(r)+1);
            } catch (ArrayIndexOutOfBoundsException e) {
                ru = r;
            }
            try {
                rd = ranksInOrder.elementAt(ranksInOrder.indexOf(r)-1);
            } catch (ArrayIndexOutOfBoundsException e) {
                rd = r;
            }
            r.setUp(ru);
            r.setDown(rd);
            ru.setDown(r);
            rd.setUp(r);
        }
    }
    private void addToRanksInOrder(Rank r) {
        ranksInOrder.addElement(r);
    }
    private String displayAsList(Vector<Rank> vr) {
        String list = "";
        for (Rank r : vr) {
            list += "~" + r.getName() + "\n";
            if (r.getUp() == null) {
                list += " +NULL\n";
            } else {
                list += " +" + r.getUp().getName() + "\n";
            }
            if (r.getDown() == null) {
                list += " -NULL\n";
            } else {
                list += " -" + r.getDown().getName() + "\n";
            }
            list += "----\n";
        }
        return list;
    }
    public static void main(String[] args) {
        for (int i=0;i<11;i++) {
            ranks.add(new Rank("Rank " + i));
        }
        System.out.println(displayAsList(sort()));
    }
}

Answers


Try this

void addToRanksInOrderWithUpDown(Rank r) {
    r.setUp(r);
    if (ranksInOrder.isEmpty()) {
        r.setDown(r);
    } else {
        Rank last = ranksInOrder.get(ranksInOrder.size() - 1);
        r.setDown(last);
        last.setUp(r);
    }
    ranksInOrder.add(r);
}

Notes:

Using Vector seems weird, it's a legacy class, use ArrayList instead.

You should not use exceptions for control flow, it is a known anti-pattern. See "Effective Java" by J.Bloch, Item 57: "Use exceptions only for exceptional conditions".


Instead of catch block of code, just try

r.setDown(r);

in your catch code.

Since addElement always adds element to the end of the Vector, there is no need to have ru at all in the first place.

public void addToRanksInOrderWithUpDown(Rank r) {
    ranksInOrder.addElement(r);
    if (ranksInOrder.size() != 1) {
        Rank rd;
        try {
            rd = ranksInOrder.elementAt(ranksInOrder.indexOf(r)-1);
            r.setUp(rd);
            r.setDown(r);
            rd.setDown(r);
        } catch (ArrayIndexOutOfBoundsException e) {
            r.setUp(r);
            r.setDown(r);
        }

    }
}

Hope this helps.


import java.util.HashSet;
import java.util.Set;
import java.util.Vector;

class Rank {
    private Rank up;
    private Rank down;
    private String name;
    public Rank getUp() {
        return up;
    }
    public Rank getDown() {
        return down;
    }
    public String getName() {
        return name;
    }
    public void setUp(Rank r) {
        up = r;
    }
    public void setDown(Rank r) {
        down = r;
    }
    public Rank(String s) {
        name = s;
    }
}

public class Ranker {
    private Set<Rank> ranks = new HashSet<Rank>();
    private Vector<Rank> ranksInOrder = new Vector<Rank>();
    public Vector<Rank> sort() {
        for (Rank r : ranks) {
            *if (ranksInOrder.size() == 0) {*
                addToRanksInOrder(r);
            } else {
                addToRanksInOrderWithUpDown(r);
            }
        }
        return ranksInOrder;
    }
    private void addToRanksInOrderWithUpDown(Rank r) {
        ranksInOrder.addElement(r);
        *int ruEx =0;int rdEx = 0;*
        if (ranksInOrder.size() != 1) {
            Rank ru, rd;
            try {
                ru = ranksInOrder.elementAt(ranksInOrder.indexOf(r)-1);
            } catch (ArrayIndexOutOfBoundsException e) {
                ru = r;
                *ruEx = 1;*
            }
            try {
                rd = ranksInOrder.elementAt(ranksInOrder.indexOf(r)+1);
            } catch (ArrayIndexOutOfBoundsException e) {
                rd = r;
                *rdEx = 1;*
            }
            r.setUp(ru);
            r.setDown(rd);
            *if(ruEx == 0){
                ru.setDown(r);
            }
            if(rdEx == 0){
                rd.setUp(r);
            }*

        }
    }
    private void addToRanksInOrder(Rank r) {
        *r.setDown(r);
        r.setUp(r);*
        ranksInOrder.addElement(r);
    }

    private String displayAsList(Vector<Rank> vr) {
        String list = "";
        for (Rank r : vr) {
            list += "~" + r.getName() + "\n";
            if (r.getUp() == null) {
                list += " +NULL\n";
            } else {
                list += " +" + r.getUp().getName() + "\n";
            }
            if (r.getDown() == null) {
                list += " -NULL\n";
            } else {
                list += " -" + r.getDown().getName() + "\n";
            }
            list += "----\n";
        }
        return list;
    }
    public static void main(String[] args) {

        Ranker r = new Ranker();
        for (int i=0;i<11;i++) {
            r.getRanks().add(new Rank("Rank " + i));
        }
        System.out.println(r.displayAsList(r.sort()));
    }
    public Set<Rank> getRanks() {
        return ranks;
    }
    public void setRanks(Set<Rank> ranks) {
        this.ranks = ranks;
    }
}

First element on the vector list will always have null for the Rank.up() since there is no more 'up' element. Unless you agree for having first element like Rank r; r.setUp(r);

Last element on the vector will always have null for the Rank.down() since there is no more 'down' element. Unless you agree for having last element like Rank r; r.setDown(r);

Therefore one of solutions would be:

public void addToRanksInOrderWithUpDown(Rank r) {

    r.setDown(r); // r will always be the last element for the moment.

    if(ranksInOrder.isEmpty()) {
        // Link r to itself.
        r.setUp(r);
    } else {
        // Link former last element to r and vice versa.
        Rank last = ranksInOrder.lastElement();
        last.setDown(r);
        r.setUp(last);
    }

    ranksInOrder.addElement(r);
}

Need Your Help

JTable and JButton

java swing java-7

i am writing java desktop application. i have some textareas to get data from user. A JButton, which takes input and process that. And a JTable to populate data processed.

Implementing button in pageradapter

android android-viewpager imagebutton

I have been working on the implementation of buttons to update a textview within my pageadapter. This is the code I have thus far for my pageadapter

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.