I am working on sorting feature for a data table. I have JSF Web Controller:
@Named
@ViewScoped
public class SearchPlayerController implements Serializable {
private List<Player> playerList;
@EJB
PlayerFacade playerFacade;
@PostConstruct
public void init() {
if (playerList == null) {
playerList = playerFacade.findAll();
}
}
// getters and setters
*
*
*
}
In this Controller I have a sorting method:
public String sortDataByClubName(final String dir) {
Collections.sort(playerList, (Player a, Player b) -> {
if(a.getClubId().getClubName()
.equals(b.getClubId().getClubName())) {
return 0;
} else if(a.getClubId().getClubName() == null) {
return -1;
} else if(b.getClubId().getClubName() == null) {
return 1;
} else {
if(dir.equals("asc")) {
return a.getClubId().getClubName()
.compareTo(b.getClubId().getClubName());
} else {
return b.getClubId().getClubName()
.compareTo(a.getClubId().getClubName());
}
}
});
return null;
}
After invoking the sort on page view, it throws NullPointerException
. I think the main reason is that inside the Comparator
it can't read the value of clubName
that should be accessible after getting Club object. Is there any possibility to compare values of nested properties?
You seem to be sorting only on Player.getClubId().getClubName()
. It seems like both getClubId()
and getClubName()
should be checked for null. This is how I would do it:
public class PlayerComparator implements Comparator<Player> {
private String dir; // Populate with constructor
public int compare(Player a, Player b) {
int result = nullCheck(a.getClubId(), b.getClubId());
if(result != 0) {
return result;
}
String aname = a.getClubId().getClubName();
String bname = b.getClubId().getClubName();
result = nullCheck(aname, bname);
if(result != 0) {
return result;
}
result = aname.compareTo(bname);
if("asc".equals(dir)) { // No NPE thrown if `dir` is null
result = -1 * result;
}
return result;
}
private int nullCheck(Object a, Object b) {
if(a == null) { return -1; }
if(b == null) { return 1; }
return 0;
}
}