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()));
}
}
Try this
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”.