I try to add some items to a JComboBox and I receive a NullPointerException error.
This is a sample of my code :
public adminPanel() {
fillComboTeacher();
initComponents();
}
public void fillComboTeacher(){
HashSet<Person> set = cont1.returnTeachers();
Iterator it = set.iterator();
try {
while (it.hasNext()) {
Person p = (Person) it.next();
String name = p.getName();
comboTeacher.addItem(name);
}
} catch (Exception e) {
System.out.println(e);
}
}
Person class - name, state (with getters and setters)
returnTeachers() - returns a HashSet containing Persons with state = "Teacher"
I don't understand why I'm receiving this error and why I can't fill the ComboBox, I followed a tutorial step-by-step and something is still not well.
Thanks!
You are calling fillComboTeacher before calling initComponents.
Looking at the method's name, I assumed that you initialized comboTeacher in the latter.
So at that point (comboTeacher.addItem(name);), comboTeacher is not yet initialized and hence the NullPointerException.
To fix this, just swap the two method calls in the constructor to initialize your components before trying to use them.
Few notes:
A NullPointerException is often easy to fix. Just look at the stacktrace (it indicates the line where the NPE occurs) and see what can be null and why at this line.
Don't use a raw iterator, but a generic one (Iterator<Person> it = set.iterator();), that will avoid you to cast the object returned by a next() call.
Since you are only reading the elements in the set, you can simply use a for-each loop for(Person p : cont1.returnTeachers()) comboTeacher.addItem(p.getName());
Related
I have an ArrayList of Student from another class called Project, and I get that Array with a method called returnPreferences() but apparently it returns a null ArrayList, even though I have added objects in that ArrayList.
Really not sure what to do, I've searched for some troubleshooting but I didn't find anything useful.
void filterAndPrintProblem(){
for(Project currentProject : listOfProjects){
ArrayList<Student> listofProjectPreferences =
currentProject.returnPreferences();
for(Student currentStudent : listofProjectPreferences){
System.out.println(currentStudent.toString());
}
}
}
void setPreferences(Project... projects){
if(listOfStudentPreferences != null){
listOfStudentPreferences = new ArrayList<>();
Collections.addAll(listOfStudentPreferences, projects);
}
}
ArrayList<Project> returnPreferences(){
return listOfStudentPreferences;
}
I want to be able to access the Objects inside the ArrayList that apparently is null.
Thanks for your time.
I'm iterating a set object to find a particular value. Is there any short way to fetch instead of iterating it? Here is my code
for(Tree t : assignedTrees) {
println t.treeName;
}
The above code will return the expected value.
assignedTrees is the set object
Set<Tree> assignedTrees = new HashSet<Tree>()
println assignedTrees will return
[Tree{id=null, treeName=Mango}]
Can I fetch the treeName instead of iterating?
You can fetch an object from a set by calling mySet.get(object). However, in your case you wish to fetch an object based on one of its attributes. The best way to do this is with a map - e.g.
Map<String, Tree> trees = new HashMap<>();
trees.put(treeObject.treeName, treeObject);
Tree myTree = trees.get("myTreeName");
Note that if you're putting your own objects into sets or maps, you must override the equals and hashcode methods, or very strange things will happen.
In general you can use lambda to find any/first element that fullfils any condition. For example:
Set<Integer> coolStrings = new HashSet<String>();
coolStrings.add("HEHE")
coolStrings.add("NOPE")
coolStrings.add("JP2GMD")
coolStrings.add("1234")
try{
String nice =
coolStrings.stream().filter(
(str) -> { return str.equals("JP2GMD") ||
str.equals("2137"); }
}).findFirst().get();
)
System.out.println("Yay, i found a REALLY cool string! : " + nice);
}
catch(NoSuchElementException e){
System.out.println("Not even one awesome string was found :(");
}
It will print "JP2GMD"
(I didn't compile it, there might be some minor syntax errors)
Working with Stream class is extremally handy (as for java standards)
I have the following code:
class Action {
public void step(Game game) {
//if some condition met,
// then remove self from action stack
game.actionStack.remove(this);
}
class Game (
public ArrayList<Action> actionStack;
public Game() {
actionStack = new Arraylist<Action>();
actionStack.add(new Action());
while (true) {
for (Action action : this.actionStack) {
action.step(this);
}
}
}
}
An exception gets thrown when game.actionStack.remove(this); occurs. Is there a way to remove the element safely from inside the Action class like I want?
I'm guessing you're getting a ConcurrentModificationException because you're calling the list remove method while iterating it. You can't do that.
An easy fix is to work on a copy of the array when iterating:
for (Action action : new ArrayList<>(this.actionStack)) {
action.step(this);
}
A slightly more efficient fix is to use an explicit Iterator and call its remove method. Perhaps have step() return a boolean indicating whether it wants to remain in the list for the next step or not:
for (Iterator<Action> it = this.actionStack.iterator(); it.hasNext();) {
Action action = it.next();
if (!action.step(this)) {
it.remove();
}
}
From : the java tutorial we get the following:
Iterators
...
Note that Iterator.remove is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.
Use Iterator instead of the for-each construct when you need to:
Remove the current element. The for-each construct hides the iterator, so you cannot call remove. Therefore, the for-each construct is not usable for filtering.
Iterate over multiple collections in parallel.
The following method shows you how to use an Iterator to filter an arbitrary Collection — that is, traverse the collection removing specific elements.
static void filter(Collection<?> c) {
for (Iterator<?> it = c.iterator(); it.hasNext(); )
if (!cond(it.next()))
it.remove();
}
This simple piece of code is polymorphic, which means that it works for any Collection regardless of implementation. This example demonstrates how easy it is to write a polymorphic algorithm using the Java Collections Framework.
Note: I assume, you implemented equals and hashCode methods for your class
You need to use iterator to remove like below;
class Game (
public ArrayList<Action> actionStack;
public Game() {
actionStack = new Arraylist<Action>();
actionStack.add(new Action());
while (true) {
for (Iterator<Action> it = this.actionStack.iterator(); it.hasNext(); ) {
it.remove();
}
}
}
}
Edit: step function is doing simple remove job. I move it to Game constructor
I suspect that you are getting a Concurrent Modification Exception. I would suggest you do it like this
class Action {
public void step(Game game) {
//if some condition met,
// then remove self from action stack
List<Action> tmpActionList = new List<Action>();
tmpActionList = game.actionStack
tmpActionList.remove(this);
game.actionStack = tmpActionList;
}
}
Let me know if it works.
In my jsf page I am calling a method called saveinsert and in my saveInsert method I have the following code.
try {
System.out.println("rchd 1");
for (Employees items : editCellItems) {
System.out.println("rchd 2");
items.setEmpId(empBean.getEmployeesId());
System.out.println("after assigning "+items.getEmployeesId());
} catch (Exception e) {
System.out.println("exception "+e.getMessage());
e.printStackTrace();
}
where editCellItems is declared like
List<Employees> editCellItems= new ArrayList<Employees>();
and empBean is declared like this
Employees empBean= new Employees();
My problem is when I run my jsf page rchd 2 and code after that is not getting invoked.
What could be the reason?
Make sure you add values into editCellItems using the List<?> add() meothod. Also When doing a for each loop make sure you do not add or remove items or you will get an Exception.
e.g.:
editCellItems.add(empBean);
edit: Also If you only have 1 element in your editCellItems, you might not want to use a list unless you are adding more,
If no objects are in editCellItems, then it will iterate through the for loop 0 times. Therefore, you need to add some objects first:
editCellItems.add(empBean);
The structure that I have is:
Map<String, ArrayList<Bean>>
This Arraylist is modified (added/removed) from different locations within different threads.
At times, some bean inside the ArrayList is becoming null. How can I track when it becomes null? I want to track what makes the bean null, to fix the bug.
This happens when the scenario is tested with a huge data set.
Here's the exact code that's failing:
for (int i = 0; i < eventlogs.size(); i++) {
MessageEventLogBean msgEventLogBean = (MessageEventLogBean) eventlogs.get(i);
eventlogs.remove(i);
try {
logWriter.write(msgEventLogBean, context);
} catch (FusionException e) {
logger.error("Error While writing the event log bean ", e);
}
}
Instead of a standard list implementation, use an anonymous class that overrides the add method and adds special code to check if the added object is null, like this:
List<T> list = new ArrayList<T>() {
public boolean add(T e) {
if (e == null) {
throw new NullPointerException("Attempt to add null to list");
}
return super.add(e);
}
};
You should similarly override all "add" methods to be sure. When code adds a null, it will explode and you will see the exception in the log and be able to see who did it be examining the stacktrace.
EDITED
To be clear, it is impossible for an object in a List to "become null". You can add a null, or you can remove an object from the List, but an object already in the List will stay there until removed.
To be clear, the only way for a null to get in the list is by putting it there - ie adding it via one of the add() methods or the addAll() method. Concurrent modification issues can not cause this issue (you may get a ConcurrentModificationException, but that still won't put a null in there).
Code such as
Object o = list.get(1);
o = null;
has no effect because you're just nulling a copy of the reference to the object - list still a reference to the object.
However, depending on the design of the Bean objects, they might be mutable. While the reference to the Bean object would remain intact, it might be possible for some of the fields within the Bean to become null. To catch this, you would need to code the setters to explode when given a null argument, either by re-writing the class, or by overloading the setters via an anonymous class (similar to my initial suggestion above).
It's a bit of work, but you can create your own List interface implementation that delegates all methods to the ArrayList. In the accessor method where you would normally return the ArrayList, instead return your debug implementation with the ArrayList wrapped inside of it. Then just set a breakpoint on your set method, and you'll know exactly what code is calling set on the ArrayList.
Perhaps this is what you intended
private final Queue<MessageEventLogBean> eventlogs = new ConcurrentLinkedQueue<>();
// this loop stops when it runs out of objects.
MessageEventLogBean msgEventLogBean;
while ((msgEventLogBean = eventlogs.poll()) != null) {
try {
logWriter.write(msgEventLogBean, context);
} catch (FusionException e) {
logger.error("Error While writing the event log bean ", e);
}
}
or
// this loops until the thread is interrupted
private final BlockingQueue<MessageEventLogBean> eventlogs = new LinkedBlockingQueue<>();
while (true) {
MessageEventLogBean msgEventLogBean = eventlogs.take();
try {
logWriter.write(msgEventLogBean, context);
} catch (FusionException e) {
logger.error("Error While writing the event log bean ", e);
}
}
Both options are thread safe.
You can override the add() and set() methods for the list so that null is invalid and throws an exception.
List<MyType> list = new ArrayList<MyType>() {
public boolean add(MyType mt) {
if(mt == null) throw new IllegalArgumentException();
super.add(mt);
}
};
Consider the following code
String a = "hi"; // a => "hi"
String b = a; // a => "hi" and b => "hi"
a = null; // a => null and b => "hi"
String a is a reference to a String and when you assign null to it you change just the value of a and other references to the same object are unaffected.
A way to process every second entry, or why using remove(i) is unlikely to be what you want.
List<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++) list.add(i);
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
list.remove(i);
}
prints
0
2
4
6
8