java 6 ArrayLists and Arrays and Generics - java

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.

Related

How can I create an array of objects in Kotlin without initialization and a specific number of elements?

I want to create an Array of objects with a specific number of elements in Kotlin, the problem is I don't now the current values for initialization of every object in the declaration, I tried:
var miArreglo = Array<Medico>(20, {null})
in Java, I have this and is exactly what I want, but i need it in Kotlin. :
Medico[] medicos = new Medico[20];
for(int i = 0 ; i < medicos.length; i++){
medicos[i] = new Medico();
}
What would be the Kotlink equivalent of the above Java code?
Also, I tried with:
var misDoctores = arrayOfNulls<medic>(20)
for(i in misDoctores ){
i = medic()
}
But I Android Studio show me the message: "Val cannot be reassigned"
The Kotlin equivalent of that could would be this:
val miArreglo = Array(20) { Medico() }
But I would strongly advice you to using Lists in Kotlin because they are way more flexible. In your case the List would not need to be mutable and thus I would advice something like this:
val miArreglo = List(20) { Medico() }
The two snippets above can be easily explained. The first parameter is obviously the Array or List size as in Java and the second is a lambda function, which is the init { ... } function. The init { ... } function can consist of some kind of operation and the last value will always be the return type and the returned value, i.e. in this case a Medico object.
I also chose to use a val instead of a var because List's and Array's should not be reassigned. If you want to edit your List, please use a MutableList instead.
val miArreglo = MutableList(20) { Medico() }
You can edit this list then, e.g.:
miArreglo.add(Medico())
If you want list of nullable objects, we can do something like this
val fragment : Array<Fragment?> = Array(4) { null }


Java - Remove "Optional" from a variable (convert)

for a piece of homework, I have to set a variable. The set method given to me, converts that into "Optional". However, I have to store this variable in an ArrayList which doesn't allow Optional variables.How can I convert the variable so it is no longer Optional?
The set method:
public void setParentVertex(IVertex<T> parentVertex)
{
if(parentVertex == null)
this.parentVertex = Optional.empty();
else
this.parentVertex = Optional.of(parentVertex);
}
Where I'm trying to use it:
ArrayList<IVertex<T>> path = new ArrayList<IVertex<T>>();
IVertex<T> parent = current.getLabel().getParentVertex();
path.add(parent);
The error I keep receiving is: "Error: incompatible types: Optional> cannot be converted to IVertex" due to the line where I declare the variable "parent".
Thank you.
Here is the correct version
List<IVertex<T>> path = new ArrayList<IVertex<T>>();
current.getLabel().getParentVertex().ifPresent(path::add)
Also it would be good to rewrite setParentVertex function:
public void setParentVertex(IVertex<T> parentVertex) {
this.parentVertex = Optional.ofNullable(parentVertex);
}
I think you don't have to add it to your list, if there is no value. So just do
if(nameOfOptional.isPresent()){
list.add(nameOfOptional.get());
}
First, add a check to find the value is present or not (by calling isPresent()) and then if the value is present then add to your ArrayList path object as shown below:
ArrayList<IVertex<T>> path = new ArrayList<>();
Optional<IVertex<T>> parent = current.getLabel().getParentVertex();
if(parent.isPresent()) {
path.add(parent.get());
}
or the shorter form is shown below which uses ifPresent method:
ArrayList<IVertex<T>> path = new ArrayList<>();
Optional<IVertex<T>> parent = current.getLabel().getParentVertex();
parent.ifPresent(path::add);
Also, I suggest you have a look at the Optional API methods here.
As a side note, I recommend you to use diamond <> operator while declaring generic types (like shown above i.e., new ArrayList<>()) , so that your code will be less verbose.

Exception occurred during event dispatching:java.lang.ClassCastException

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.

Using User input for the reflection process in java

basically am trying to make java command prompt. Suppose user enters as input from the user:
new x java.util.ArrayList
here x is the object name and java.util.ArrayList is the class. So this script inputed by the user means create an object of class java.util.ArrayList.
Now suppose that user enter:
new x java.util.ArrayList int:5
means create an object x of the java.util.ArrayList and make its size 5. Like this i want that everytime i input something related to object creation as input i should be able to create class its object and its method based on the input that the user does. Am new to java and reflection so kindly help! here is the code i thought so far using my mind:
public static void token_classification() throws ClassNotFoundException
{
my_hash = new HashMap();
Keep_Obj_Info = new HashMap();
if(expression_keeper[0].equalsIgnoreCase("new"))
{
my_hash.put("Object", expression_keeper[1]);
Class Obj= Class.forName(expression_keeper[2]);
Keep_Obj_Info.put("Modifier", Obj.getModifiers());
Keep_Obj_Info.put("Package",Obj.getPackage());
////????
Constructor[] constructors = Obj.getConstructors();
}
else
if(expression_keeper[0].equalsIgnoreCase("call"))
{
}
else
if(expression_keeper[0].equalsIgnoreCase("print"))
{
}
else
{
System.out.println("Invalid Script!");
}
}
ExpressionKeeper is basically a String array that keeps the user input in tokenized form. Meaning anything next to a white space to a new location.
Well for Object creation in java; the constructor and it's arguments are required.
you can have a generic framework which will accept input from command prompt and interpret them means find out the data type of the input ex : number/string/char/boolean etc..
Also your framework should know the argument index for example say a constructor has 2 parameter and one is string and another is int. and say first parameter is int and 2nd parameter is String and while passing the parameter from the command line the user first pass string and then int in that scenario your program should be smart enough to properly arrange them in order. So many such things you need to take care of....Now coming to the example which you have mentioned for ArrayList you can write a program as follows : (I have just given you a pseudocode you can implement your own way)
{
int howManyParametersFromCommandLine = getnoParameterCount; //it will maintain no.of parameters passed from command line
String[] parametersFromCommandLine = getParametersFromcommandLine(); // Ex : {1,"ABC",new Double(80.0d)};
List<Class> parameterTypesList = parseParameters(parametersFromCommandLine); //This will identify type of each of the parameter
Class clazz = Class.forName("youClassName");
Constructor[] cons = clazz.getConstructors();
for(Constructor c : cons)
{
Class[] parameterTypes = c.getParameterTypes();
if(parameterTypes.length == howManyParametersFromCommandLine)
{
//try to match the parameter type in parameterTypesList with parameterTypes if this matches then
boolean typeMatchingAndSequecneSucess = matchParameters(parameterTypes,parameterTypesList);
if(typeMatchingAndSequecneSucess)
{
if(c.isAccessible())
{
Object[] initargs = parseAndRetActualParamValue(parametersFromCommandLine);
return c.newInstance(initargs);
}
}
}
}
}
Hope this will help you !!
You may want to use the Interpreter design pattern. It is used just for that.
The Interpreter is a bit complex, but will ensure you code interpretation works right. Also, it gives you a easy inclusion of new commands.
Take a look at here: http://en.wikipedia.org/wiki/Interpreter_pattern
Hope I could help.

Nightmare Class - floats/strings

This is my class reponsible for new item entries, and from the start it has been a complete nightmare, I can't seem to resolve the issues I am facing which are:
setStock(float) in Item cannot be applied to ()
Item entry:
private void writeItemRecord()
{
// Check to see if we can connect to database table
if ( DataBaseHandler.makeConnectionToitemDB() == -1)
{
JOptionPane.showMessageDialog (frame, "Unable to connect to database table (Item)");
}
else // Ok, so first read data from the text fields
{
// Read data from form and store data
String Itemname = ItemnameTxtField.getText();
String Itemcode = ItemcodeTxtField.getText();
String Description = DescriptionTxtField.getText();
String Unitprice = UnitpriceTxtField.getText();
String Style = StyleTxtField.getText();
String Finish = FinishTxtField.getText();
String Stock = StockTxtField.getText();
// Convert priceStr to a float
Float fvar = Float.valueOf(Unitprice);
float price = fvar.floatValue();
Float svar = Float.valueOf(Stock);
float stock = svar.floatValue();
// Create a Item oject
Item Item = new Item();
// Set the attributes for the Item object
Item.setItemname (Itemname);
Item.setItemcode (Itemcode);
Item.setDescription (Description);
Item.setUnitprice (price);
Item.setStock(stock);
Item.setStyle(Style);
Item.setFinish(Finish);
// Write Item record. Method writeToItemTable() returns
// 0 of OK writing record, -1 if there is a problem. I store
// the returned value in a variable called error.
int error = DataBaseHandler.writeToItemTable(Item.getItemname(),
Item.getItemcode(),
Item.getDescription(),
Item.getUnitprice(),
Item.setStock(),
Item.setStyle(Style),
Item.setFinish(Finish),
Item.setSuppliercode(Suppliercode),
Item.setSuppliername(Suppliername),
Item.setAddress(Address)
);
// Check if there is a problem writing the record, in
// which case error will contain -1
if (error == -1)
{
JOptionPane.showMessageDialog (frame, "Problem writing record to Item Table");
}
// Clear the form - actual method is coded below
clearForm();
// Close database connection. Report an error message
// if there is a problem.
if ( DataBaseHandler.closeConnection() == -1 )
{
JOptionPane.showMessageDialog (frame, "Problem closing data base conection");
}
}
} // End
Any help is much appreciated!
And item extracts:
public void setStock(float StockIn)
{
Stock = StockIn;
}
public float getStock()
{
return Stock;
}
For starters, adhere to Java naming conventions. Nothing except class/interface names is allowed to use CamelCase. Use lowerCamelCase. As for your "problem", you wrote
Item.setStock(),
so obviously it's giving you the error. It is also giving you the exact line number of the error, something that would obviously have helped us to diagnose your problem.
Solution: use Item.getStock() (i suppose, it's hard to tell). Calling Item.setStock at that position (as an argument to a method call) is meaningless anyway, given that setStock is a void method.
Java compiler errors come with a line number - pay attention to it. This is your problem:
Item.setStock()
setStock() requires a parameter, you are trying to call it without one. Perhaps you meant getStock()? And I suspect that all the calls to set methods in the parameter list to writeToItemTable are also wrong, as those set methods will have void as return value, so you can't use them that way.
The setStock method looks like this:
public void setStock(float StockIn)
To call it, you need to pass a float as an argument. Somewhere in your code, you call the method, like this:
Item.setStock(),
The method needs to be called with the float argument, but instead it's called with none, hence you see a compilation error.
In this code:
int error = DataBaseHandler.writeToItemTable(Item.getItemname(),
Item.getItemcode(),
Item.getDescription(),
Item.getUnitprice(),
// Right here --> Item.setStock(),
Item.setStyle(Style),
Item.setFinish(Finish),
Item.setSuppliercode(Suppliercode),
Item.setSuppliername(Suppliername),
Item.setAddress(Address)
);
Notice that you're calling Item.setStock(), Item.setStyle(Style), etc. instead of Item.getStock(), Item.getStyle(), etc. This is probably the source of your problem - you're trying to call the setStock() method with no arguments, hence the error.
Hope this helps!
This line
// Create a Item oject
Item Item = new Item();
Is problematic. Not only is it bad style in Java to use uppercase names for variables, this particular instance results in a compile error. Also, you're calling setStock without a parameter. You need to fix that as well.
Here is your error:
int error = DataBaseHandler.writeToItemTable(Item.getItemname(),
Item.getItemcode(),
Item.getDescription(),
Item.getUnitprice(),
Item.setStock(), // <<< here! should be getStock()
Item.setStyle(Style),
Item.setFinish(Finish),
Item.setSuppliercode(Suppliercode),
Item.setSuppliername(Suppliername),
Item.setAddress(Address));
But again... consider naming/coding conventions.

Categories