java: unable to cast an Integer object to String - java

I'm trying to concatenate multiple objects inside a String variable called 'update' from a 'data' array within the method 'addClient' below:
public int addClient(Object[] data) {
try {
if (((String)data[0]).trim().isEmpty() || ((String)data[1]).trim().isEmpty() || ((int)data[2] < 0) || ((int)data[3] <= 0)) {
return StatusBar.ERR_INVALID_INPUT_CODE;
}
// the line below is causing the exception
String update = "INSERT INTO Client VALUES(" + ((String)data[0]).trim() + "," + ((String)data[1]).trim() + "," + ((Integer)data[3]).intValue() + "," + ((Integer)data[4]).intValue() + "," + ((Boolean)data[2]).booleanValue() + "," + ((String)data[5]).trim() + ")";
if (statement.executeUpdate(update) != 1) {
return StatusBar.ERR_INTERNAL_CODE;
}
}
catch (Exception e) {
e.printStackTrace();
return StatusBar.ERR_INTERNAL_CODE;
}
return StatusBar.ERR_SUCCESS_CODE;
}
However when the code above executes; an exception gets raised showing the following message:
java.lang.ClassCastException: java.lang.Integer cannot be cast to
java.lang.String
at Model.addClient(Model.java:43)
The 'data' object array is obtained through the call of the following method:
public Object[] getFields() {
return new Object[]{jTextFieldName.getText(), jTextFieldAddress.getText(),
jComboBoxType.getSelectedIndex(),
jSpinnerPhone.getValue(), jSpinnerFax.getValue(),
jTextFieldWebsite.getText()};
}
I did many searches and tried many methods including String.valueOf and Integer.toString, but without any success ..
Why I'm getting such behavior? How can it be solved?

You have a lot of options casting to String.
You chose the "simple" option that will work only if the object is really a String, and you just need to down-cast it (from Object) to String.
Try using one of the following options:
new String (your-Integer-here);
(your-Integer-here).toString();
(your-Integer-here) + "";
Let me know if it's working now :)

The elements of your data array can be of any reference type. Therefore you can't cast them to String without checking their type first.
Luckily, you can simply call their toString method instead.
Change
((String)data[0])
to
data[0].toString()

Instead of casting to String, you can call .toString() method on object, if that is your intention.
You are casting your object
i.e
if (((String)data[0]).trim().isEmpty() || ((String)data[1]).trim().isEmpty() || ((int)data[2] < 0) || ((int)data[3] <= 0)) to
if (data[0].toString().trim().isEmpty() || (data[1].toString().trim().isEmpty() || ((int)data[2] < 0) || ((int)data[3] <= 0))
Assuming data[3] and data[2] are of type Integers.
*PS:You can also log the values, to make sure what the values are.

You can try as below and let me know how it goes.
private static void concater(){
String[] data={"abc","def","23","45","true","xyz"};
String update = "INSERT INTO Client VALUES(" + ((String)data[0]).trim() + "," + ((String)data[1]).trim() + "," + Integer.parseInt(data[2]) + "," +
Integer.parseInt(data[3]) + "," + Boolean.parseBoolean(data[4]) + "," + ((String)data[5]).trim() + ")";
System.out.println(update); //INSERT INTO Client VALUES(abc,def,23,45,true,xyz)
}

Related

JAVA Discord Bot (java.lang.ArrayIndexOutOfBoundsException)

I have a weird problem. Since I'm new in coding, maybe I am dumb and I don't know how can I resolve this issue, so the issue is, I have 2 commands for my discord bot, permanent mute, and temporary mute. I want to make something like a placeholder to be used in config.yml since it will be more configurable, but when I use args[], I have a weird problem, here is it :
[JDA MainWS-ReadThread] ERROR net.dv8tion.jda.api.JDA - One of the EventListeners had an uncaught exception
java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
at me.trashlord.bot.events.TempMuteCommand.onGuildMessageReceived(TempMuteCommand.java:34)
at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:396)
at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:96)
at net.dv8tion.jda.internal.hooks.EventManagerProxy.handleInternally(EventManagerProxy.java:82)
at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:69)
at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:166)
at net.dv8tion.jda.internal.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:97)
at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:36)
at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:921)
at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:808)
at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:786)
at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:959)
at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385)
at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276)
at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996)
at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755)
at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108)
at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64)
at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45)
ALSO, here is my code at those lines :
String[] args = event.getMessage().getContentRaw().split("\\s+");
String MutedMessage = ConfigManager.INSTANCE.getSetting("MutedMessage")
.replaceAll("%muteduser", args[1]);
String UnMutedMessage = ConfigManager.INSTANCE.getSetting("UnMutedMessage")
.replaceAll("%unmuteduser", args[1]);
String TempMuted1 = ConfigManager.INSTANCE.getSetting("TempMutedMSG")
.replaceAll("%tempmutedusr", String.valueOf(event.getGuild().getMemberById(args[1].replaceAll("[^\\d]+", ""))))
.replaceAll("%tempmutetime", args[2]);
if (args[0].equalsIgnoreCase(Commands.prefix + "mute")) {
if (Objects.requireNonNull(event.getMember()).hasPermission(Permission.MESSAGE_MANAGE)) {
if (args.length == 2) {
Member member = event.getGuild().getMemberById(args[1].replaceAll("[^\\d]+", ""));
Role role = event.getGuild().getRoleById(MutedRole);
if (!Objects.requireNonNull(member).getRoles().contains(role)) {
// Mute user
event.getChannel().sendMessage(MutedMessage).queue();
event.getGuild().addRoleToMember(member, Objects.requireNonNull(role)).complete();
} else {
// Unmute user
event.getChannel().sendMessage(UnMutedMessage).queue();
event.getGuild().removeRoleFromMember(member, Objects.requireNonNull(role)).complete();
}
} else if (args.length == 3) {
Member member = event.getGuild().getMemberById(args[1].replaceAll("[^\\d]+", ""));
Role role = event.getGuild().getRoleById(MutedRole);
//event.getChannel().sendMessage(TempMuted1 + " " + args[1] + " " + TempMuted2 + " " + args[2] + " " + TempMuted3).queue();
event.getChannel().sendMessage(TempMuted1).queue();
event.getGuild().addRoleToMember(Objects.requireNonNull(member), Objects.requireNonNull(role))
.complete();
// Unmute after a few seconds
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
event.getChannel().sendMessage(TempUnMuted + " " + args[1] + ".").queue();
event.getGuild().removeRoleFromMember(member, role).complete();
}
},
TimeUnit.MINUTES.toMillis(Integer.parseInt(args[2]))
);
} else {
event.getChannel().sendMessage("Incorrect syntax. Use `~mute [user mention] [time {optional}]`")
.queue();
}
}
}
}
}
the problem is you are trying to get an element from args[2], which may the array only contains 2 elements (length 2) in the following code:
String TempMuted1 = ConfigManager.INSTANCE.getSetting("TempMutedMSG")
.replaceAll("%tempmutedusr", String.valueOf(event.getGuild().getMemberById(args[1].replaceAll("[^\\d]+", ""))))
.replaceAll("%tempmutetime", args[2]);
Note that in java arrays are zero-based and indexes start from 0 to length - 1.
You can take this code inside the if-condition:
else if (args.length == 3) {
String TempMuted1 = ConfigManager.INSTANCE.getSetting("TempMutedMSG")
.replaceAll("%tempmutedusr", String.valueOf(event.getGuild().getMemberById(args[1].replaceAll("[^\\d]+", ""))))
.replaceAll("%tempmutetime", args[2]);
// your code
}
Are you sure that this line from your code:
String TempMuted1 = ConfigManager.INSTANCE.getSetting("TempMutedMSG")
.replaceAll("%tempmutedusr", String.valueOf(event.getGuild().getMemberById(args[1].replaceAll("[^\\d]+", ""))))
.replaceAll("%tempmutetime", args[2]);
args[1] and args[2] is correct?
If the length is 2, Then args[2] is looking for the 3rd value and you might not have it...
Have a further look on how length and index works for arrays.

How can i return multiple getters from my method?

I have made a method that is requesting a column from my MySQL database. Fortunately this is working, but i am trying to acces the return value. Because i want to acces the getters and setters for Voedingsmiddel. A new Voedingsmiddel is created inside the method and later returned. The values of the database are assigned as the attributes of the voedingsmiddel. This method is created in my Database class and i am trying to acces it within another class.
If i am trying to acces voedingsmiddel outside of the method, it is nog giving me an object, instead it is giving me the datalocation Voedingsmiddel#6f7fd0e6.
I was able to get some of the result i am trying to get. I achieved it by changing public Voedingsmiddel getVoedingsmiddelBijId to public double getVoedingsmiddelBijId. I also changed return voedingsmiddel; into voedingsmiddel.getCalorieen; So i was able to get 1 of the getters.
By calling the method Database.getVoedingsmiddelBijId(int).getCalorieen();
Intellij is telling me the following (Result of'Voedingsmiddel.getCalorieen()' is ignored).
public Voedingsmiddel getVoedingsmiddelBijId(int idVoedingsmiddel) {
Voedingsmiddel voedingsmiddel = new Voedingsmiddel("", 0, 0,0,0,0);
try {
String query = "select * from voedingsmiddel where idVoedingsmiddel = ?";
PreparedStatement preparedStatement = myCon.prepareStatement(query);
preparedStatement.setInt(1, idVoedingsmiddel);
myRes = preparedStatement.executeQuery();
while (myRes.next()) {
int idvoedingsmiddel = myRes.getInt("idVoedingsmiddel");
String naam = myRes.getString("naam");
int gram = myRes.getInt("gram");
double calorieen = myRes.getDouble("calorieën");
double koolhydraten = myRes.getDouble("koolhydraten");
double eiwitten = myRes.getDouble("eiwitten");
double vetten = myRes.getDouble("vetten");
voedingsmiddel = new Voedingsmiddel(naam, gram, calorieen, koolhydraten, eiwitten, vetten);
System.out.println("idVoedingsmiddel " + idvoedingsmiddel + " naam " + naam + " gram " + gram + " calorieën " + calorieen + " koolhydraten " + koolhydraten + " eiwitten " + eiwitten + " vetten " + vetten);
}
} catch (Exception exc) {
exc.printStackTrace();
System.out.println("Error: " + exc);
}
return voedingsmiddel;
}
First of all, i would really appreciate it, if someone could explain me what i am doing wrong. Also a solution to the problem would be more then welcome!
The expected result is that the return value of the method would be an object instead of what i think is a datalocation. So i can call the getters and setters for that object.
I have a history of posting too much code and not enough information. So i hope this is better, if not feel free to correct me.

Better string manipulation code

I'm looking for an efficient (one line) string manipulation code to achieve this, regex probably.
I have a string, for example, "Calvin" and I need to convert this to "/C/a/l/Calvin".
i.e. take first three characters, separate them using '/' and later append the original string.
This is the code I've come up with and its working fine, just looking for a better one.
String first = StringUtils.substring(prodName, 0, 1);
String second = StringUtils.substring(prodName, 1, 2);
String third = StringUtils.substring(prodName, 2, 3);
String prodPath = path + "/" + first + "/" + second + "/" + third + "/" + prodName + "/" ;
prodName.replaceAll("^(.)(.)(.).*", "/$1/$2/$3/$0")
What is the point of StringUtils.substring(prodName, 0, 1) when the built-in prodName.substring(0, 1) will do the same thing??
Anyway, assuming prodName is always at least 3 characters long (since you didn't give rules for expected output if it is not), this is the fastest way to do it:
String prodPath = path + '/' +
prodName.charAt(0) + '/' +
prodName.charAt(1) + '/' +
prodName.charAt(2) + '/' +
prodName + '/';
Normally, char + char is integer addition, not string concatenation, but since the first value is a String, and the + operator is left-associative, all + operators are string concatenations, not numeric additions.
How about using String.charAt
StringBuilder b = new StringBuilder (path);
b.append ('/').append (prodName.charAt (0))
.append ('/').append(prodName.charAt (1))
.append ('/').append(prodName.charAt (2))
.append ('/').append (prodName).append ('/');
Don't use regex for simple stuff like this. You may save a couple lines, but you loose a lot in readability. Regex usually take some time to understand when reading them.
String s = path;
for (int i = 0; i < 3; i++)
s += prodName.substring(i,i+1) + "/";
s += prodName
You can use MessageFormat.format()
MessageFormat.format("{0}/{1}/{2}/{3}/{4}/", baseDir, name.charAt(0), name.charAt(1), name.charAt(2), name);
imho i would wrap it for readability,
private String getProductionDirectoryPath(String baseDir, String name) {
return MessageFormat.format("{0}/{1}/{2}/{3}/{4}/", baseDir, name.charAt(0), name.charAt(1), name.charAt(2), name);
}
Positive look ahead can be used
public static void main(String[] args) {
String s = "Calvin";
System.out.println(s.replaceAll("(?=^(\\w)(\\w)(\\w))", "/$1/$2/$3/"));
}
O/P:
/C/a/l/Calvin
No use of a regex, but a simple split over nothing =)
String[] firstThree = prodName.split("");
String prodPath = path + "/" + firstThree[0] + "/" + firstThree[1] + "/" + firstThree[2] + "/" + prodName + "/";
Another approach is using charAt():
String prodPath = path + "/" + prodName.charAt(0) + "/" + prodName.charAt(1) + "/"+ prodName.charAt(2) + "/" + prodName + "/";
You said efficient but you maybe meant terse. I doubt either should be an objective, so you have a different problem.
Why do you care that this string transformation requires four lines of code? Are you concerned that something that in your mind is one operation ("create transformed string") is spread over four Java operations? You should extract the four lines of Java into their own method. Then, when you read the code where the operation is needed you have one conceptual operation ("create transformed string") corresponding to one Java operation (call a method). You could call the methid createTransformedString to make the code even clearer.
You can use String Builder:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 3; i++) {
sb.append("/").append(prodName.charAt(i));
}
sb.append('/').append(prodName);
Or you can put all the code in loop:
int size = 2;
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= size; i++) {
if (i == 0)
sb.append('/');
sb.append(prodName.charAt(i)).append("/");
if (i == size)
sb.append(prodName);
}

Basic XML parsing issues. Cannot find node names via Java XmlStreamReader method. Any ideas?

Having no luck in parsing some basic XML. I'm doing this in the Apex language, but it's syntactically nearly identical to Java and in this case uses java.xml.stream.XMLStreamReader as its XML parsing engine.
The problem is: I'm having no luck getting to any of the actual XML node names. The getLocalName() method within the XmlStreamReader class always returns null for all nodes as I loop through them.
code is here
Very basic functionality at this point. If you run this, you will see that reader.getLocalName() always returns null and so do all accompanying methods (getNameSpace(), getLocation(), getPrefix()).
Any ideas why? I'm stuck with the XML arriving in the format it's in...so I have to parse it as-is. I could use various workarounds (regEx, counting nodes, etc.) but those are messy and not ideal.
I have reformed your code into one block that can be tested in the workbench's anonymous execution window. I run the code and then filter the Execution Log to show USER_DEBUG statements. The output shows node names and text as you would expect.
I think the key is to use the APEX methods hasText() and hasName().
String XML_STR = '<document>' + '<result>success</result>' +'<resultcode>000000</resultcode>' +
'<note></note>' + '<item>' +'<quantity>1</quantity>' +
'<fname>Bob</fname>' +'<lname>Tungsten</lname>' +
'<address>23232 Fleet Street</address>' +'<city>Santa Clara</city>' +
'<state>CA</state>' +'<zip>94105</zip>' +
'<country>United States</country>' +'<email>blahblahblah#blahblahblah.com</email>' +
'<phone>4155555555</phone>' +'</item>' +'</document>';
XmlStreamReader reader = new XmlStreamReader(XML_STR);
while (reader.hasNext()) {
System.debug('$$$ reader.getEventType(): ' + reader.getEventType());
if (reader.hasName()) {
System.debug('$$$ reader.getLocalName(): ' + reader.getLocalName());
// System.debug('$$$ reader.getNamespace(): ' + reader.getNamespace());
// System.debug('$$$ reader.getprefix(): ' + reader.getprefix());
}
if (reader.hasText()) {
System.debug('$$$ reader.getText(): ' + reader.getText());
}
System.debug('$$$ Go to next');
reader.next();
}
Here is another solution based on the recipe by Jon Mountjoy
http://developer.force.com/cookbook/recipe/parsing-xml-using-the-apex-dom-parser
private String walkThrough(DOM.XMLNode node) {
String result = '\n';
if (node.getNodeType() == DOM.XMLNodeType.COMMENT) {
return 'Comment (' + node.getText() + ')';
}
if (node.getNodeType() == DOM.XMLNodeType.TEXT) {
return 'Text (' + node.getText() + ')';
}
if (node.getNodeType() == DOM.XMLNodeType.ELEMENT) {
result += 'Element: ' + node.getName();
if (node.getText().trim() != '') {
result += ', text=' + node.getText().trim();
}
if (node.getAttributeCount() > 0) {
for (Integer i = 0; i< node.getAttributeCount(); i++ ) {
result += ', attribute #' + i + ':' + node.getAttributeKeyAt(i) + '=' + node.getAttributeValue(node.getAttributeKeyAt(i), node.getAttributeKeyNsAt(i));
}
}
for (Dom.XMLNode child: node.getChildElements()) {
result += walkThrough(child);
}
return result;
}
return ''; //should never reach here
}
private String parse(String toParse) {
DOM.Document doc = new DOM.Document();
try {
doc.load(toParse);
DOM.XMLNode root = doc.getRootElement();
return walkThrough(root);
} catch (System.XMLException e) { // invalid XML
return e.getMessage();
}
}
String XML_STR = '<document>' + '<result>success</result>' +'<resultcode>000000</resultcode>' +
'<note></note>' + '<item>' +'<quantity>1</quantity>' +
'<fname>Bob</fname>' +'<lname>Tungsten</lname>' +
'<address>23232 Fleet Street</address>' +'<city>Santa Clara</city>' +
'<state>CA</state>' +'<zip>94105</zip>' +
'<country>United States</country>' +'<email>blahblahblah#blahblahblah.com</email>' +
'<phone>4155555555</phone>' +'</item>' +'</document>';
System.debug(parse(XML_STR));

Idea Live Template to Log Method Args

I would like to be able to create a live template in Jetbrain's Idea that will log the method's arguments. Let's call it "larg". It would work like:
public void get(String one, String two) {
larg<tab>
to create
public void get(String one, String two) {
log.info("get: one = " + one + " two = " + two);
I'm fine with getting the method name in, but have not figured out how to pull in the method arguments. Any ideas?
I'm 4 years late, but the predefined template soutp pretty much does this using a groovyscript variable.
Here's the groovy script that does what you're looking for
groovyScript("'\"' + _1.collect { it + ' = [\" + ' + it + ' + \"]'}.join(', ') + '\"'", methodParameters())
Looks like it is not currently possible with a live template.
From the Jetbrain's forum:
There is no predefined live template function to do this for you automatically.
You can write a plugin that would provide such a function.
this is my groovy script
groovyScript("import com.intellij.psi.*;import com.intellij.psi.util.PsiTreeUtil; def file = PsiDocumentManager.getInstance(_editor.project).getPsiFile(_editor.document); PsiMethod method = PsiTreeUtil.findElementOfClassAtOffset(file, _editor.caretModel.offset, PsiMethod.class, false); PsiParameter[] parameters = method == null ? PsiParameter.EMPTY_ARRAY : method.parameterList.parameters; return parameters.size() == 0 ? '' : '\"' + method.name + ' : ' + parameters.collect { def prefix = it.name + ' = '; def type = it.type; return type instanceof PsiArrayType ? type.componentType instanceof PsiPrimitiveType ? prefix + '\" + java.util.Arrays.toString(' + it.name + ')' : prefix + '\" + java.util.Arrays.deepToString(' + it.name + ')' : prefix + '\" + ' + it.name }.join(' + \", ')", methodParameters())
In Android Studio in Kotlin I use this to log classname, methodname and parameters.
I use my name as tag to easily filter in logcat. I use these mainly for debugging, I don't commit these messages with my name.
Log.d("MYNAME", "$CLASS_NAME$:$METHOD_NAME$: $PARAMETERS$")
And then the parameters are defined as follows.
CLASS_NAME : kotlinClassName()
METHOD_NAME : kotlinFunctionName()
PARAMETERS : groovyScript("'' + _1.collect { it + ' = $' + it}.join(', ') ", functionParameters())
This would be the result if used in the main activity
fun aFunctionWithParameters( first: Int, second: String, third: ArrayList<String>){
Log.d("MYNAME", "MainActivity:aFunctionWithParameters: first = $first, second = $second, third = $third")
}
I based my solution on Rob's answer and edited it to my needs.

Categories