Polyov
Polyov

Reputation: 2321

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()));
    }
}

Upvotes: 0

Views: 349

Answers (4)

rawo
rawo

Reputation: 21

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);
}

Upvotes: 1

Renjith
Renjith

Reputation: 3274

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;
    }
}

Upvotes: 1

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136092

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".

Upvotes: 1

LPD
LPD

Reputation: 2883

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.

Upvotes: 1

Related Questions