I'm having a problem with retrieving and casting ArrayList from session. I get the following error:
javax.servlet.ServletException: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
I stored the arrayList in the session:
List<UserApplication> userList = uaDAO.searchUser(eds);
if (!userList.isEmpty()) {
request.getSession().setAttribute("userList", userList);
action_forward = EDITSUCCESS;
and for casting the session object to ArrayList, did the following:
EditStudentForm edt = (EditStudentForm)form;
if ((session.getAttribute("userList")) instanceof List){
List <UserApplication> studtList = (ArrayList<UserApplication>)session.getAttribute("userList");
}
try {
uaDAO.editUser(edt,studtList);
action_forward = EDITSUCCESS;
}
I'm getting the error over here in the DAO class:
public void editUser(EditStudentForm edt,List studtList) throws Exception {
PreparedStatement pst = null;
StringBuilder sb = new StringBuilder();
int stCode =Integer.parseInt(studtList.get(1).toString()); GETTING ERROR HERE
if (edt.getTitle() != null && !edt.getTitle().equals(studtList.get(2).toString())) {
sb.append("title = '").append(edt.getTitle()).append("'");
}
.
.
You are explicitly asking for 2nd (studtList.get(1)) and 3rd (studtList.get(2)) item in the list but never really make sure this list is big enough. Moreover your code apparently doesn't even compile:
if ((session.getAttribute("userList")) instanceof List){
List <UserApplication> studtList = ///...
}
try {
uaDAO.editUser(edt,studtList);
studtList is unaccessible in try block, also parenthesis in if statement are unmatched.
Check your studtList value.
From the error it seems your studtList only contain one item and you're try to get the second item with this code :
int stCode =Integer.parseInt(studtList.get(1).toString());
Change your code like this :
public void editUser(EditStudentForm edt,List studtList) throws Exception {
PreparedStatement pst = null;
StringBuilder sb = new StringBuilder();
if(studtList.size() > 1)
int stCode =Integer.parseInt(studtList.get(1).toString()); GETTING ERROR HERE
if (studtList.size() > 2 && edt.getTitle() != null && !edt.getTitle().equals(studtList.get(2).toString())) {
sb.append("title = '").append(edt.getTitle()).append("'");
}
}
In studtList there are no two elements and size of list maybe 1 or 0 elements, you should check it before try to call studtList.get(1). In ArrayList indexing start from 0 and if you want get first element you should call studtList.get(0).
In this code:
EditStudentForm edt = (EditStudentForm)form;
if ((session.getAttribute("userList")) instanceof List){
List <UserApplication> studtList = (ArrayList<UserApplication>)session.getAttribute("userList");
}
try {
uaDAO.editUser(edt,studtList);
action_forward = EDITSUCCESS;
}
You create a new variable 'studtList' that is never used. It's scope is only the { } pair around that one line.
There has to be another variable by that same name, studtList, in the outer scope so the 'editUser()' call can work.
Additional Note
As the other folks have answered, it looks like you may be doing a .get(1) and expecting the first element of the array list. Maybe. Maybe not.
Related
Given a dependency tree of "Scenarios", I'm calculating the "weight" of each scenario branch.
I need to detect circular dependencies (scenario1 -> scenario2 -> scenario3 -> scenario1).
I'm currently doing a breadth-first search and passing a list down the recursion chain, however I'm not able to detect a circular dependency.
Each iteration I add the current scenario (String) to the List and then check dependsOnScenarios (an array of scenario names).
I should be just checking if a string is contained within a list of Strings but this scenario never catches it.
Am I adding to/checking the List at the wrong time?
Edit:
allScenarios is: a ConcurrentHashMap<String, Scenario>
dependsOnScenarios is a String[] and a property of Scenario
name is a String and a property of Scenario
getWeight is initially called with an empty list:
s.priority = getWeight(s, new ArrayList<String>())+1;
Input:
Scenario g1=new Scenario("Scenario1" , null);
Scenario g2=new Scenario("Scenario2" , new String[]{"Scenario4"});
Scenario g3=new Scenario("Scenario3" , new String[]{"Scenario1","Scenario2"});
Scenario g4=new Scenario("Scenario4" , new String[]{"Scenario3"});
Code:
private static int getWeight(Scenario scenario, List<String> visited) throws Exception{
int numDep = 0;
visited.add(scenario.name);
if(scenario.dependsOnScenarios != null){
for(String dependency:scenario.dependsOnScenarios) {
if(visited.contains(dependency)){
throw new Exception("Circular Reference: "+dependency+" has already occured");
}
return scenario.dependsOnScenarios.length + getWeight(allScenarios.get(dependency),visited);
}
}
return numDep;
}
My problem was that I was returning from the loop before I could evaluate and check the entire list. I needed to be using an additional loop to check everything fully fist.
private static int getWeight(Scenario scenario, List<String> visited) throws Exception{
int numDep = 0;
visited.add(scenario.name);
if(scenario.dependsOnScenarios != null){
for(String dependency:scenario.dependsOnScenarios) {
if(visited.contains(dependency)){
throw new Exception("Circular Reference: "+String.join("->",visited)+"->"+dependency);
}
}
for(String dependency:scenario.dependsOnScenarios) {
return scenario.dependsOnScenarios.length + getWeight(allScenarios.get(dependency),visited);
}
}
return numDep;
}
This is hw and I am really stuck on how to get my code to return what I want it to return. I am trying to return a String value with a given index value. I thought all I had to do was return the string value at the given index but I am not getting the right answer.
public void add(String candidate){
if (candidate.equals(null)){
throw new RuntimeException();
}
String[] contenders = new String[candidates.length+1];
// copy the array manually because I'm restricted from ArrayLists
for (int i = 0; i < candidates.length; i++){
contenders[i] = this.candidates[i];
}
this.candidate = candidate;
contenders[contenders.length-1] = this.candidate;
this.candidates = new String [contenders.length];
After adding values to a newly constructed array the tester wants to get the string value at a given index
public String get(int index){
if (index < 0 || index > candidates.length) {
throw new RuntimeException("Your argument was not within bounds.");
}
for (int i = index; i < candidate.length(); i++){
candidate = candidates[index];
}
return candidate;
I have been working on it and I finally was able to have candidate stop pointing to null it is giving the wrong value for the given index so for example I want 'X' at candidate[3] but I am getting 'Y' because that is the last value that candidate keeps. I have tried just returning candidates[index] but then it tells me that the value at that index is null. As I have gone through the debugger it appears that my original array is not being copied over properly but I am not sure what I should try next. Thanks in advance.
This is my constructor:
public CandidateList(){
candidates = new String[0];
}
public CandidateList(String[] candidates){
this.candidates = new String[candidates.length];
CandidateList candidateList = new CandidateList();
There is a lot that can be improved in your code, let me add some comments
public void add(String candidate){
//if candidate is actually null you are calling null.equals
//which means this will always result in a NullPointerException
//you can remove this if if you want
if (candidate.equals(null)){
throw new RuntimeException();
}
...
//think about what you are doing here,
//you are setting this.candidates to a new empty array
//(is big contenders.length, but still empty)
this.candidates = new String [contenders.length];
Second part:
public String get(int index){
//you are missing an '=' in index >= candidates.length
if (index < 0 || index > candidates.length) {
throw new RuntimeException("Your argument was not within bounds.");
}
//this for loop is wrong, you are changing 'i' but never use it..
//just return candidates[index] like you said before.
//It was probably null because of the error above
for (int i = index; i < candidate.length(); i++){
candidate = candidates[index];
}
return candidate;
A note on the RuntimeException(RE): if you catch a NullPointerException (NPE) and throw a RE you are actually losing information (since NPE is a more specific error rather than RE). If you want to catch/throw put at least a significant message like "candidate cannot be null"
Let's now analyze the constructor:
public CandidateList(){
candidates = new String[0];
}
public CandidateList(String[] candidates){
// you are doing the same error as above here:
// when you do this you create an EMPTY list of size candidates.lenght
// correct code is this.candidates = candidates
this.candidates = new String[candidates.length];
// this is not necessary, constructors don't need to return anything,
//here you are just creating a new instance that will not be used anywhere
CandidateList candidateList = new CandidateList();
Constructors create objects, they don't return data. I suggest you to take a look at this question Does a Java constructor return the Object reference? and in general read a bit more about constructors
How I can get those values from this object? I was trying to getFields, getDeclaredFields etc. but everything is empty.
The problem is that Field[] myField = o.getClass().getDeclaredFields(); always return an empty array.
I am getting those values from database this way:
Query reqDisplayResponse = em.createNativeQuery("Select * FROM pxds_displayResponse");
List<Object> displayResponseList = reqDisplayResponse.getResultList();
And I want to print those values:
for(Object o: displayResponseList) {
for(Field field: o.getClass().getDeclaredFields()) {
log.info(field.getName());
}
}
Unfortunately log.info is unreachable.
Ok, here is solution. In fact object is an array, getDeclaredFields() return empty table, in documentation we can read:
If this Class object represents an array type, a primitive type, or void, then this method returns an array of length 0.
So in this situation it is useless. All we have to do is iterate over this object this way:
for(Object o: displayResponseList) {
for(int i = 0; i < 7; i++) {
System.out.println(((Object[])o)[i].toString());
}
System.out.println("...............");
}
Hope this will help someone in future.
You should use getDeclaredField, and then use get on it, passing the object as parameter.
Like this:
Field myField = object.getClass().getDeclaredField("_myField");
myField.setAccessible(true);
return (Integer) myField.get(object);
Try to display the object 'o' like an array:
for(int index = 0 ; index < 10 ; index++){
Log.info(String.valueOf(o[index]));
}
I think those fields you are trying to access are private
So in order to access private fields you have to:-
for (Field f : object.getClass().getDeclaredFields()) {
f.setAccessible(true);
Object o;
try {
o = f.get(object);
} catch (Exception e) {
o = e;
}
System.out.println(f.getGenericType() + " " + f.getName() + " = " + o);
}
This is an ID given by the Eclipse debugger, not by Java. You cannot access it.
There is System.identityHashCode(Object) to get the Object identity. (not the same ID)
If you want an ID like the one shown in the Eclipse debugger, you'd have to allocate them yourself.
Here is some general direction how you could do something like that:
Elegant way to assign object id in Java
Gwozdz, I think I understand your question. If I understood correctly, you are having problemas to access the value from a list of objects, in your image code example I'm seeing that you are using List. Try to use List<Object[]> and then use a foreach to access every value of your matrix.
List<Object[]> displayResponseList = reqDisplayReponse.getResultList();
foreach(.....){
foreach(.....){
[manipulate you object value here]
}
}
Just for your information: Matrix is a list of lists. In that case a list of array.
I receive this exception
Exception in thread "Thread-3" java.util.ConcurrentModificationException
at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
at java.util.LinkedList$ListItr.next(LinkedList.java:696)
at ServerMultiThread.run(ServerMultiThread.java:89)
at java.lang.Thread.run(Thread.java:680)
from this code:
synchronized(itemsList)
{
if(itemsList.isEmpty())
{
item.initCounter();
itemsList.add(item);
pw.println("It's the first time you connect to server!");
}
else
{
for(ItemClient itm : itemsList)
{
if(itm.equals(item))
{
int value = itm.getCounter();
value++;
itm.setCounter(value);
pw.println(itm.getCounter());
}
else
{
item.initCounter();
itemsList.add(item);
pw.println("It's the first time you connect to server!");
}
}
}
}
the row 89 corresponds to this for(ItemClient itm : itemsList). Why I receive this error?
You are changing the LinkedList content inside the for-each loop. The implementation of the LinkedList iterator checks on the next call to next() if the list has changed and throws the exception (sad I know ...).
The enhanced for loop is used to iterate over the given set of values, but during iteration you are modifying the contents of the same, that's why you getting that error, instead use a normal for loop to do your stuff for this thing.
Regards
Sadly, there is no easy way around it. As the others have said, you cannot modify a collection inside this kind of loop. Your other option is to use a normal for loop. However, accessing a LinkedList by index like:
for(int i = 0; i < list.size(); i++) {
list.get(i);
}
takes O(N) time for each item, because the linked list needs to be traversed from the beginning each time.
If the linked list is not essential to your algorithm, I suggest you to use an ArrayList instead and change your code as follows:
for(int i = 0; i < itemsList.size(); i++) {
itm = itemsList.get(i);
if(itm.equals(item)) {
int value = itm.getCounter();
value++;
itm.setCounter(value);
pw.println(itm.getCounter());
} else {
item.initCounter();
itemsList.add(item);
pw.println("It's the first time you connect to server!");
}
}
This will not throw the exception, but it's still not a nice piece of code because you are adding to the list while iterating and that is never a good idea.
I hope you had patience to read so far!
My final suggestion for you is to hold a temporary list of elements that you need to add and append them to the initial list at the end of the loop. This way you can keep all your original code and the LinkedList:
LinkedList<ItemClient> tempList = new LinkedList<ItemClient>();
for(ItemClient itm: itemsList) {
itm = itemsList.get(i);
if(itm.equals(item)) {
int value = itm.getCounter();
value++;
itm.setCounter(value);
pw.println(itm.getCounter());
} else {
item.initCounter();
tempList.add(item);
pw.println("It's the first time you connect to server!");
}
}
itemsList.addAll(tempList);
I am trying to get data from LivEx table as list, and then save that data into two dimensional array called array. My method is returning object[][].
I made up this code from googling here and there and taking bits from every example, however I am doing something wrong which I can't quite seem to put my finger on. It gives me an exception which is a NullPointerException whenever I call getLivExList(currentPlan).
Here is my code:
public static Object[][] getLivExList(String currentPlan) throws Exception {
Session s = null;
try {
s = HibernateUtil.getSessionFactory().getCurrentSession();
s.beginTransaction();
String query = "select F.item, F.category, F.amount from LivEx F where F.planName=?";
Query q = s.createQuery(query);
System.out.println(query);
List fp = q.list();
s.getTransaction().commit();
Object array[][] = new Object[fp.size()][3];
for (int i = 0; i < fp.size(); i++) {
for (int j = 0; j < 3; j++) {
array[i][j] = fp.get(j +(3 * i));
}
}
System.out.println("getLivExdata in networthentitymanager OKAY");
return array;
} catch (Exception e) {
System.out.println("problem at getLivExdata in networthentitymanager");
throw e;
} finally {
if (s != null) {
HibernateUtil.closeSession();
}
}
Please help me find out where the problem is coming from.
This is the exception I am getting:
SEVERE: null
org.hibernate.QueryException: Expected positional parameter count: 1, actual parameters: [] [select F.item, F.category, F.amount from LivEx F where F.planName=?]
0 problem
at org.hibernate.impl.AbstractQueryImpl.verifyParameters(AbstractQueryImpl.java:319)
at org.hibernate.impl.AbstractQueryImpl.verifyParameters(AbstractQueryImpl.java:275)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:75)
at com.elitconsultancy.finplanner.entity.NetWorthEntityManager.getLivExList(NetWorthEntityManager.java:213)
You're not setting the plan name for the query, even 'though you've specified a positional parameter (?).
Put this before your call to list:
query.setString(0, currentPlan);
List fp = q.list();
s.getTransaction().commit();
Object array[][] = new Object[fp.size()][3];
you are getting size of list. If list returned by q.list() is null, that is no matching rows found then you will get Null pointer exception.
Thats the first thing i see that might be wrong in the code
before invoking methods on list, u can check whether it is null or not.