Reputation: 2321
I've got objects (Rank
s) 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
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
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
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
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