I've been receiving ClassCastException in my code. Objective initially was to convert Set to List since the refreshDetailVOTable method will only get Set. The problem could have been in converting Set to List. refreshDetailVOTable might took the wrong List that's why I'm receiving ClassCastException. Any thoughts on this?
public List deleteChildPromotionComponentDetails(ClientContext context, List detailIRsToDelete,
String emergencyAccessPermission) throws RetekBusinessException {
List exclusionList = null;
RpmEvent deleteEvent = buildPromotionComponentDetailsDeleteEvent(emergencyAccessPermission);
deleteEvent.setTransitionNotificationExceptionFlag(true);
Set detailBOsToDelete = new HashSet();
for (Iterator iDetails = detailIRsToDelete.iterator(); iDetails.hasNext();) {
IdentifiableReference detailIR = (IdentifiableReference) iDetails.next();
PromotionComponentDetail promotionComponentDetail = (PromotionComponentDetail) getService()
.readForUpdate(detailIR);
Set exclusionSet = promotionComponentDetail.getExceptionsAndExclusions();
exclusionList = new ArrayList (exclusionSet);
for(Iterator exclusion = exclusionSet.iterator(); exclusion.hasNext();){
PromotionComponentDetail exclusionDel = (PromotionComponentDetail) exclusion.next();
exclusionDel.accept(deleteEvent);
detailBOsToDelete.add(promotionComponentDetail);
}
}
return exclusionList;
}
public void deleteChildDetails(final List parentComponentDetails)
{
List list = null;
try {
list = getCmlPromotionComponentDetailAppService().deleteChildPromotionComponentDetails(
ClientContext.getInstance(), parentComponentDetails,
emergencyPermission.getName());
} catch (RetekBusinessException e) {
e.printStackTrace();
}
refreshDetailVOTable(list);
}
Take a look at the generics tutorial here:
http://docs.oracle.com/javase/tutorial/java/generics/
You're doing pretty simple stuff, so you only need to look at the first part. You probably don't need to dive into wildcards.
A guess as to what's happening: your method is receiving a parameter List detailIRsToDelete from which you get an iterator and iterate over the elements like so:
for (Iterator iDetails = detailIRsToDelete.iterator(); iDetails.hasNext();) {
IdentifiableReference detailIR = (IdentifiableReference) iDetails.next();
...
}
If whoever calls you had accidentally put something other than an IdentifiableReference into detailIRsToDelete, you'd get a ClassCastException in the assignment statement within the loop. If instead the list parameter were declared
List<IdentifiableReference> detailIRsToDelete
the act of putting things into this list would be checked by the compiler, and the error would occur at the point where the erroneous object was added, at compile time, instead of later at runtime, as you're experiencing.
Related
I have objects Bullet that I add to two ArrayLists at once, the lists are briefly described below. After certain operations are done I wish to remove a bullet from both lists. Is this approach correct? I keep on getting an error: java.util.ConcurrentModificationException
Alternatively, can you think of a better solution than ArrayList for the purpose of handling objects in this manner?
//there are ArrayList<Bullet> bullets and ArrayList<Updatable> updatable, in the class
public void removeBullet(Bullet bullet) {
for (ListIterator<Bullet> bulletIterator = bullets.listIterator(); bulletIterator.hasNext();) {
Bullet tempBullet = bulletIterator.next();
if (tempBullet.equals(bullet)) {
for (ListIterator<Updatable> updatableIterator = updatable.listIterator(); updatableIterator.hasNext();) {
Updatable tempUpdatable = updatableIterator.next();
if (tempUpdatable.equals(bullet)) {
updatableIterator.remove();
bulletIterator.remove();
return;
}
}
}
}
}
EDIT: The source of problem was that I used an iterator on one of the lists, at exact same time in a different place, hence the error. This code worked fine for the updatable list.
A ConcurrentModificationException happens because you are trying to remove a bullet from an Iterator which you are also simultaneously iterating through in a for loop; java doesn't like when you do that and will throw the exception.
To solve this, you would have to iterate through both Iterators and remove them separately, or, as rdonuk stated, simply use the ArrayList remove() method, which will not throw any exceptions if you try to remove something that isn't in the ArrayList; it will return true if the object was removed, or false otherwise, so you don't even have to check if the object you want to remove is contained in the ArrayList in the first place.
Just use ArrayList remove method.
bullets.remove(bullet);
and
updatable.remove(bullet);
Edit:
remove method of iterator which used by ArrayList:
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
As you see it is already use ArrayList.remove() method.
I have a varargs method and I want to call the method using 1 or 0 arguments.
The following code compiles, but does not run correctly:
final List<MyMessage> allMessages = new ArrayList<MyMessage>();
MyMessage message = null;
if (checkSomeCondition()) {
message = new MyMessage(someParam);
allMessages.add(message);
}
int size = allMessages.size();
MyMessage[] msgArrayType = new MyMessage[size]; // ERROR
MyMessage[] msgArray = allMessages.toArray(msgArrayType);
callFunc(msgArray);
...........
public void callFunc(MyMessage... messages) {
}
When I debug the code, after the line that I marked with //ERROR, the value of the array msgArrayType is com.sun.jdi.ClassNotLoadedException: Type has not been loaded occurred while retrieving component type of array.
This is also wrong:
MyMessage[] msgArray = (MyMessage[]) allMessages.toArray();
// -> java.lang.Object cannot be cast to .......MyMessage
I really don't understand it, because allMessages is a List of MyMessages!
The only option I see is to use something like
if (message == null) {
callFunc();
} else {
callFunc(message);
}
but I was wondering how the code would look like if I want to write callFunc only once. Any suggestions?
If you want to use varargs, which excepts an array - you should also make sure that the elements passed are non null.
So if you just want to use one function call of callfunc() and don't want to surround with if-else block you can use the following function call.
callfunc(message == null ? (Object)null : message);
This will either pass in the message object wrapped in array, or it will pass an array with single null element.
Usually, in java, to delete an item from a stack (or set) I would do something along the lines of:
Stack<Particle> particles = new Stack<Particle>();
int i = 0, ;
while(i < particles.size()) {
if(particles.elementAt(i).isAlive()) {
i ++;
} else {
particles.remove(i);
}
}
I've searched the android docs and googled quite a few times in an attempt to achieve the same results, but nothing seems to work. Can anyone help me here?
Try looping using an Iterator, since per Oracle Iterator.remove() is the only safe way
to remove an item from a Collection (including a Stack) during iteration.
From http://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html
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.
So something like the following should work:
Stack<Particle> particles = new Stack<Particle>();
... // Add a bunch of particles
Iterator<Particle> iter = particles.iterator();
while (iter.hasNext()) {
Particle p = iter.next();
if (!p.isAlive()) {
iter.remove();
}
}
I've used this approach in a real Android app (OneBusAway Android - see code here), and it worked for me. Note that in the code for this app I also included a try/catch block in case the platform throws an exception, and in this case just iterate through a copy of the collection and then remove the item from the original collection.
For you, this would look like:
try {
... // above code using iterator.remove
} catch(UnsupportedOperationException e) {
Log.w(TAG, "Problem removing from stack using iterator: " + e);
// The platform apparently didn't like the efficient way to do this, so we'll just
// loop through a copy and remove what we don't want from the original
ArrayList<Particle> copy = new ArrayList<Particle>(particles);
for (Particle p : copy) {
if (!p.isAlive()) {
particles.remove(p);
}
}
}
This way you get the more efficient approach if the platform supports it, and if not you still have a backup.
Have you ever try this:
Stack<String> stack = new Stack<String>();
stack.push("S");
stack.push("d");
for (String s : stack){
stack.pop();
}
I have a method from which i am returning object like
public static Object login(DataManager dataManager, String userName, String password)
ArrayList<LoginCredentialsBean> loginCredentialsList = new ArrayList<LoginCredentialsBean>();
String authenticated = "false";
Connection connection = null;
try {
connection = dataManager.getConnection();
} catch (Exception e) {
return ("Having problem in connectiong to databaste: " + e.getMessage());
}
if (connection != null) {
try {
...
try {
ResultSet rs = prepStatement.executeQuery();
try {
while (rs.next()) {
...
loginCredentialsList.add(new LoginCredentialsBean(roleId, orgaCode, passwordExpiryDate, date, status, language));
authenticated = "true";
} //end of while()
} finally {
rs.close();
}
} finally {
prepStatement.close();
}
if (authenticated.equals("true")) {
updateUserLogByInserting(connection, userName);
}
} catch(SQLException e) {
System.out.println("Could not login from dataabse:" + e.getMessage());
} finally {
dataManager.putConnection(connection);
}
}
if (authenticated.equals("true")) {
return loginCredentialsList;
} else {
return authenticated;
}
} //end of login()
Now i am testing it like
public static void main(String... args) {
MoneyTreeServices moneyTreeServices = new MoneyTreeServices();
Object result = moneyTreeServices.login("Admin", "cbas1234");
if (result instanceof ArrayList<?>) {
System.out.println("ArrayList instance");
}
System.out.println(result);
}
It returns me result like
ArrayList instance
[pk.mazars.moneyTree.bean.LoginCredentialsBean#b7ec5d]
I want to ask i am using condition like ArrayList<?>. How can i check that ArrayList that contain LoginCredentialsBean object. Like when i use
if (result instanceof ArrayList<LoginCredentialsBean>) {
}
i get error that
Can not perform instanceof check against parameterized type ArrayList<LoginCredentialsBean>. Use the form ArrayList<?>
I want to check instanceof ArrayList and arraylist has LoginCredentialsBean ?
Thank you.
The short answer is that you can't. Generics are implemented via type erasure - they're effectively a compile-time syntactic sugar to ensure you don't put an Integer into a List<String>.
The runtime objects themselves, however, are just the raw types. An instance of ArrayList doesn't know that it's an ArrayList<String> (or rather, that it was assigned to a variable with that generic type). So when you interrogate it with reflection, you cannot get any generic type info.
There are two broad types of solution I can think of. One is to iterate over the list contents and check their dynamic type - if the first element is a LoginCredentialsBean, for example, then it's reasonable to assume that you have a List<LoginCredentialsBean>. This won't work for empty lists though, which could be a problem, and can potentially give false positives (e.g. a List<Object> allParameters might happen to have a LoginCredentialsBean as its first element...)
The other is to explicitly pass metadata objects around - so in this case you'd return the Object from the login method, along with a token which describes what type of object it is. This could be a simple enum constant; or going to the other extreme you could make the tokens generically typed, such that the compiler can check this against the type of what you're returning and ensure that the tokens are type-correct.
But in any case, instanceof is too little (information), too late.
Mind you, your login method looks... odd. I don't think it should return an Object at all, as that's just lazy and completely subverting the static type system which would help you here. Rather, I think it should just return a List<LoginCredentialsBean> containing the credentials that pertain to the given login.
You have three different paths where you return. The first is if an exception is encountered when connecting to the database - in which case you should throw an exception! Returning a string with the error details is very atypical and confusing - an exceptional condition should be handled as an Exception, that's what they're for.
The other two situations are ones where you're able to look up definitive results. For the failed login case, I would just return an empty list (i.e. this username/password has no credentials whatsoever), while returning the populated list during a successful login.
If you strongly want to be able to distinguish between a login failure, and a successful login (with no credentials), then perhaps return a compound object instead, such as:
class LoginStatus {
final boolean authenticated;
final List<LoginCredentialsBean> credentials;
}
Either way, the caller knows exactly what they're getting back, and can call methods on it appropriately without having to call instanceof and typecast.
Parameterized type info is erased at compile time and instanceof is resolved at (fanfare) runtime - that is why you get that error.
What you could do is iterate over the elements in the List and instanceof them.
Cheers,
You have to check it twice.
if (result instanceof ArrayList<?>) {
System.out.println("ArrayList instance");
//cast
ArrayList<LoginCredentialsBean> list = (ArrayList<LoginCredentialsBean>) result;
///..check if list contains LoginCredentialsBean
for(int i=0; i<list.size(); i++){
if(list.get(i) instanceof LoginCredentialsBean){
System.out.println("LoginCredentialsBean instance");
}
}
}
There is no such thing like "ArrayList that contain LoginCredentialsBean"
ArrayList contains Objects, all the time.
you must iterate over the list and check each object:
for (Object o: result) {
if (!(o instanceof LoginCredentialsBean)) {
//Fail
}
}
you can use the contains(Object o) to check whether the ArrayList contains your object. With the instanceof List to check whether the given object is a List. Because of type erasure at runtime the generic type of the List wont be available
If your login method returns an Object type there is no way to check this the way you try.
Type parameters exist only on compile-time due to type erasure. You need to check if retuned object is a List or Collection or just Iterable, then iterate throuh it and check every item, if it is a instance of LoginCredentialsBean.
However, your code is an example of bad design. A method that returns a String or a list is just wrong. To make it right:
make it return List<LoginCredentialsBean>
throw a checked exception if authentication fails
public static List<LoginCredentialsBean> login(DataManager dataManager, String userName, String password) throws AuthenticationException {...}
Note: Use boolean to keep logical data instead of "true" or "false" strings.
I have a function "getStudent()" that returns an ArrayList of strings and when i call this function in another class, i get a NullPointerException, i thought i had correctly initialized my List.
Here are the two functions and the line i get a NullPointerException is in bold.
public ArrayList<String> getStudents(){
try
{
System.out.println("gets here ");
Statement newStat = this.conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet res = newStat.executeQuery("SELECT FirstName FROM Students");
String data = "";
while (res.next()){
studentList.add(res.getString("FirstName"));
}
}
catch(SQLException e){
System.err.println("SQLException: " + e.getMessage());
}
return studentList;
}
Function that calls 'getStudents()'
public class CancelListener implements ActionListener{
private Main_Menu menu;
private ArrayList<String> arrayList = new ArrayList<String>();;
Iterator iterator = arrayList.iterator();
public CancelListener(Main_Menu menu) {
this.menu = menu;
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getActionCommand().equalsIgnoreCase("Cancel")){
**arrayList = StudentModel.getStudents();**// NULLPOINTER EXCEPTION
while(iterator.hasNext()){
System.out.println(iterator.next().toString());
}
this.menu.resetStudent();
}
}
}
Your StudentModel variable is probably null. The code you posted doesn't show how that variable is initialized so I can't tell you exactly what you're doing wrong, but when you reach the line marked it must be null.
You should check that you are initializing that variable correctly before you try to use it.
You probably didn't initialize StudentModel. But I can't tell for sure since this part of the code doesn't appear here.
getStudents() isn't static, and it looks like you're calling it as a static method (judging by the way you've capitalized StudentModel.) So, as others have already said, you probably need to instantiate a StudentModel object, then call instance.getStudents().
Further, I don't see where you're creating an array instance. getStudents() adds items to studentList, but we don't see how studentList is initialized. This might also be the problem. Frankly, given what you're doing, there's probably no reason to make studentList an instance variable. So just declare the variable locally and allocate the array in the getStudents() method.
You mentioned that you think you initialized the list correctly, but this isn't what you are getting the exception on. Also, you may have another problem.
You get an iterator for your list:
Iterator iterator = arrayList.iterator();
Then you assign a different object to that reference:
arrayList = StudentModel.getStudents();// NULLPOINTER EXCEPTION
Then you try to use the iterator:
while(iterator.hasNext()){
My understanding is that this shouldn't cause an exception, since you're not making changes to list the iterator refers. But, you are almost certainly iterating through a different list that you think you are. Is it possible you may be mis-interpreting an exception that is somehow caused here?