How to ignore null values when reading from a form? - java

I have the following block of code in my Java program:
Filter.sitesToBeFiltered.add(eid.getSite());
System.out.println("Entity Site added to ArrayList. ");
Filter.applicationsToBeFiltered.add(eid.getApplication());
System.out.println("Entity Application added to ArrayList. ");
Filter.IDsToBeFiltered.add(eid.getEntity());
System.out.println("Entity ID added to ArrayList");
Filter.positionsToBeFilteredX.add(position.getX());
System.out.println("Entity X position added to ArrayList. ");
Filter.positionsToBeFilteredY.add(position.getY());
System.out.println("Entity Y position added to ArrayList. ");
Filter.positionsToBeFilteredZ.add(position.getZ());
System.out.println("Entity Z position added to ArrayList. ");
Currently, it will read the values of a set of JTextFields, and add each value to an associated ArrayList. (The ArrayLists are either ArrayLists of Integers or Doubles). However, it will read their values no matter whether the value is a String, int/ double or null...
I want to add some error checking code, so that it will only add the value to the associated ArrayList if it is of the correct data type. I've tried doing this by surrounding each of the two-line blocks in the code displayed above with an 'if' statement, such as:
if(eid.getSite() != null){
Filter.sitesToBeFiltered.add(eid.getSite());
System.out.println("Entity Site added to ArrayList. ");
}
But if I do this, I get a compile error on the if statement that says "The operator != is undefined for the argument type(s) int, null"... Why is this? What should I use to check that the value of the JTextFields are not equal to null instead?

try with:
if(eid != null && eid.getSite()) {
doSomething();
}

If it is int (primitive type) you will always get 0 if no value is set.
If for 0 nothing is assigned at UI side, then try to ignore zero if (!eid.getSite() == 0) but please make sure that 0 dont have any meaning.
With string you can cast return object to string if it's Object class, and check for not blank

I managed to solve this by adding the error checking code to where I was reading the values in from the JTextFields. So instead of:
filter1Type = String.valueOf(Gui.filter1.getSelectedItem());
filter1Value = Integer.parseInt(Gui.filter1Text.getText());
I now have:
filter1Type = String.valueOf(Gui.filter1.getSelectedItem());
if(isNumeric(Gui.filter1Text.getText()){
filter1Value = Integer.parseInt(Gui.filter1Text.getText());
} else {
filter1Value = 0;
//Display some error message to the user here.
}
So now, any value entered into the filter1Text JTextField that is not numeric will automatically be converted to 0, and a message will be displayed to the user telling them to enter a valid value.

First of all,you can control the empty TextFields using the trim method. This control must be used before you assign textField value to the arraylist.
Before control textField value is empty or not,then assign to the arraylist.
String controlledText = eid.getText().trim();//read contents of text area into 'TextField'
if(!controlledText.equals("")){
//doSometing();
}

Related

java split a string and put into an array position

So i am using string.split because i need to take certain parts of a string and then print the first part. The part size may vary so I can't use substring or a math formula. I am attempting to store everything I need in the string array to then selectively print what I need based on the position, this much I can control. However, I am not sure what to do because I know when I do a split, it takes the two parts and stores them in the array. However, there is one case where I need that value in the array untouched. I'm afraid if I do
format[0] = rename
That it will overwrite that value and mess up the entire array. My question is how do I assign a position to this value when I don't know what the position of the others will be? Do I need to preemptively assign it a value or give it the last possible value in the array? I have attached a segment of the code that deals with my question. The only thing I can add is that this is in a bigger loop and rename's value changes every iteration. Don't pay to much attention to the comments, those are more of reminders for me as to what to do rather than what the code is suppose to do. Any pointers, tips, help is greatly appreciated.
String format[];
rename = workbook.getSheet(sheet).getCell(column,row).getContents();
for(int i = 0; i < rename.length(); i++) {
//may need to add[i] so it has somewhere to go and store
if(rename.charAt(i) == '/') {
format = rename.split("/");
}
else if(rename.charAt(i) == '.') {
if(rename.charAt(0) == 0) {
//just put that value in the array
format = rename;
} else {
//round it to the tenths place and then put it into the array
format = rename.split("\\.");
}
} else if(rename.charAt(i) == '%') {
//space between number and percentage
format = rename.split(" ");
}
}
Whenever you assign a variable it gets overwritten
format[0] = rename
Will overwrite the first index of this array of Strings.
In your example, the 'format' array is being overwritten with each iteration of the for loop. After the loop has been completed 'format' will contain only the values for the most recent split.
I would suggest looking into using an ArrayList, they are much easier to manage than a traditional array and you can simply just iterate through the split values and append them at the end.

Why is this variable set to empty string when it is already initialized to an empty string?

I have taken the following code snippet from the 5th snippet on this developer guide on Content Providers.
The confusion is that in the first statement String[] mSelectionArgs = {""};, mSelectionArgs[0] IS set to "".
Then later if the mSearchString is empty (TextUtils.isEmpty(mSearchString)), then again mSelectionArgs[0] is assigned "".
So the question is that why are they setting it to an empty string when it is already initialized to an empty string?
/*
* This defines a one-element String array to contain the selection argument.
*/
String[] mSelectionArgs = {""};
// Gets a word from the UI
mSearchString = mSearchWord.getText().toString();
// Remember to insert code here to check for invalid or malicious input.
// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
// Setting the selection clause to null will return all words
mSelectionClause = null;
mSelectionArgs[0] = "";
} else {
// Constructs a selection clause that matches the word that the user entered.
mSelectionClause = UserDictionary.Words.WORD + " = ?";
// Moves the user's input string to the selection arguments.
mSelectionArgs[0] = mSearchString;
}
...
I like it, because it's symmetric
if something
var = x
else
var = y
It's clear what var is under each condition, without needing to go back and visit its initial value.
Except for additional clarity and code readability, as noted in another answer, this coding style makes for a less error prone code which is easier to maintain.
This way, if the initial value of mSelectionArgs is changed, or new code added which overrides this value before the execution of the if-else block, the code of this block will still execute correctly. Without this "rudimentary" assignment, a change as described above could lead to a bug which would be very difficult to trace.
As a side note:
This specific code snippet is not that good (yes, I know it is from Android Developers site...) - if you pass null as selection argument to query(), then it is better to also pass null as selectionArgs argument. I'd modify this sample to something like this (setting both selection and selectionArgs to null):
// Gets a word from the UI
mSearchString = mSearchWord.getText().toString();
// Remember to insert code here to check for invalid or malicious input.
String[] mSelectionArgs = null;
// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
// Setting the selection clause to null will return all words
mSelectionClause = null;
mSelectionArgs = null;
} else {
// Constructs a selection clause that matches the word that the user entered.
mSelectionClause = UserDictionary.Words.WORD + " = ?";
// Moves the user's input string to the selection arguments.
mSelectionArgs = new String[] {mSearchString};
}
Edit: why the above code snippet is better than the original one?
It is not an error to pass null as selection and non-null as selectionArgs. This array will be passed to the specific ContentProvider you're addressing, and shouldn't be used at all since selection does not contain any ? placeholders. Any ContentProvider violating this assumption is buggy. Although not an error, it just looks weird - why do you pass an object that should be ignored anyway? This also has performance cost (which is higher if ContentProvider runs in different process), which is proportional to the size of the object being passed.
Edit 2: why the above code snippet is MUCH better than the original one?
Turns out that what I said above might be misleading. I found it out the hard way:
Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 3 because the index is out of range. The statement has 1 parameters.
at android.database.sqlite.SQLiteProgram.bind(SQLiteProgram.java:212)
at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:166)
at android.database.sqlite.SQLiteProgram.bindAllArgsAsStrings(SQLiteProgram.java:200)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
The above exception was thrown because I tried to pass selectionArgs which contained more elements than the number of ? placeholders in selection.
These two methods from SQLiteProgram.java are to "blame" for this exception:
public void bindAllArgsAsStrings(String[] bindArgs) {
if (bindArgs != null) {
for (int i = bindArgs.length; i != 0; i--) {
bindString(i, bindArgs[i - 1]);
}
}
}
private void bind(int index, Object value) {
if (index < 1 || index > mNumParameters) {
throw new IllegalArgumentException("Cannot bind argument at index "
+ index + " because the index is out of range. "
+ "The statement has " + mNumParameters + " parameters.");
}
mBindArgs[index - 1] = value;
}
Now, when I found out about this behavior, I think that the code example from Android Developers site is not just inefficient, but is a total crap!
Bottom line: if you pass null as selection, pass null as selectionArgs as well. If selection is not null and contains ? placeholders - make sure that the length of selectionArgs array equals the number of ? placeholders in selection.

Java contains method

I have a problem with a contains (...) method from List <...> class. I'm trying to check if a expression (that is loaded from user input) already exist in a List, but if I entered same name as twice, it said there's nothing same in the List. Please help, there's source code:
boolean checker;
checker = expressions.contains(line[1]);
if (checker == true) {
System.err.println("This expression has already been declared!");
return index;
}
PS: line[1] is a second index in array from main function that stores user-entered line split by whitespaces. (First index of line need to be always 'var', and second is any word that cannot be twice in the List)
Your list may not have exact same string as provided in the input which may be due to white spaces. Try trimming the input and then call contains
checker = expressions.contains(line[1].trim());

Copy a string splitted to another string

In some place of a class I have declared a temporal String variable:
String name;
Which I will use to store data from a text. The text have many fields with these two types of format:
Type: text/html
name=foo
For this case, I am particularly interested in the fields of the type name=foo
So, I breaked previously the lines of the text using split
String lines[] = text.split("\n");
And, again, I will use split to identify the fields of the type mentioned. In the code below, the while cycle stops where it detects a name=foo field, and prints the value of that field in the console.
int i = 0; // Counter for the while cycle
while (!(lines[i].split("=")[0].equals("name"))) {
i++;
if (lines[i].split("=")[0].equals("name")) // If the field is name...
System.out.println(lines[i].split("=")[1]); // Prints the value of the field
name = lines[i].split("=")[1]; // <-- My problem is here
}
My problem starts when I want to copy the value of the field to the String variable mentioned early, giving me an java.lang.ArrayIndexOutOfBoundsException.
I need that String to do something with it later. Any idea to safely copy the value of that field to a String variable?
Adding paranthesis to your if saves you from two problems:
if a line contains no = the whole String is in [0] and accessing [1] will result in said Exception
you are changing (overwriting) the variable name regardless of the condition
To please the compiler you may also want to intialize name to something like null.
int i = 0; // Counter for the while cycle
while (!(lines[i].split("=")[0].equals("name"))) {
i++;
if (lines[i].split("=")[0].equals("name")){ // If the field is name...
System.out.println(lines[i].split("=")[1]); // Prints the value of the field
name = lines[i].split("=")[1]; // <-- My problem is here
}
}
In your code:
String name;
name = lines[i].split("=")[1];
Here name will overwrite every time.
I think you are looking for something like this:
String names[];
String lines[] = text.split("\n");
names[] = new String[lines.length];
And inside you while loop do it like:
names[i] = lines[i].split("=")[1];
There are quite a few things to note about your code:
you probably miss {} after the if-statement and therefore update name every run of the while-loop
you access [1] without checking how many elements the split("=") yielded
you literally call split("=") 4 times on almost every line. Save CPU-time by introducing a temporary variable!
you can replace your while-loop by a for-loop which also finds name=value in the first line and does not "throw up" if name=value is not inside any of the lines (you don't check whether i is less than lines.length)
I left your comments inside my answer; feel free to remove them.
Variant a (using an index):
for (int i = 0; i < lines.length; i++) {
// Only split once and keep X=Y together in name=X=Y by specifying , 2
final String[] split = lines[i].split("=", 2);
if (split.length == 2 && split[0].equals("name")){ // If the field is name...
System.out.println(split[1]); // Prints the value of the field
name = split[1]; // <-- My problem is here
break; // no need to look any further
}
}
Variant b (using "for-each"):
for (String line : lines) {
// Only split once and keep X=Y together in name=X=Y by specifying , 2
final String[] split = line.split("=", 2);
if (split.length == 2 && split[0].equals("name")) { // If the field is name...
System.out.println(split[1]); // Prints the value of the field
name = split[1]; // <-- My problem is here
break; // no need to look any further
}
}
I suppose your problem is when you reach the last line or a line which doesn't contains a "=" sign. You are checking
!(lines[i].split("=")[0].equals("name"))
but then you add 1 to i, so maybe this condition now is false
if (lines[i].split("=")[0].equals("name"))
and you will get java.lang.ArrayIndexOutOfBoundsException here
name = lines[i].split("=")[1];
if the line doesn't contains a "=".
Try
if (lines[i].split("=")[0].equals("name")) { // If the field is name...
System.out.println(lines[i].split("=")[1]); // Prints the value of the field
name = lines[i].split("=")[1];
}

preventing twice run inside android's textwatcher

im working with android's TextWatcher for doing this: when user type, save what typed and after saving, change characters inside Edittext. for example, i have a constant text like"hi im happy" , and every thing i type in edittext user sees that this text is writing(this string shows Tandemly while user typing)! but main text that user types, stored in a variable . i use this code inside afterTextChanged:
if(s.toString().charAt(s.length()-1) != 'a'){
//save inside freaktext variable(append)
freaktext=freaktext+s.toString().charAt(s.length()-1);
//change edittext value(what user see's)
txtfreak.setText(s.toString().substring(0, s.length()-1) + "a");
txtfreak.setSelection(txtfreak.getText().length());
}else{
freaktext=freaktext+"a";
}
i this code i say, if typed character is not "a", save it on a variable named "freaktext" and then change edittext value and put "a" character to the end of string inside edittext. but if user types "a" just save it in freaktext.
bu my problem is: when user types a none "a" character, everything works fine and my code save typed character and then modify edittext value, but when edittext value changes whole code runs again and because last time i change it and put an "a" to it, my code's second part (else) runs and again save an "a" to the end of saved string. in fact when i type "q" i see "qa" in my saved string!! i want that just user directly type "a" in the keyboard, "a" saved and in other situations not. i fact my else section only runs when user directly pressed on "a" key on the keyboard.how i can do this? please help me, this code waste my time for 1 day
Outside your function, somewhere:
boolean weChangedIt = false;
Inside afterTextChanged:
if (weChangedIt) {
weChangedIt = false;
} else {
if(s.toString().charAt(s.length()-1) != 'a'){
weChangedIt = true;
freaktext=freaktext+s.toString().charAt(s.length()-1);
txtfreak.setText(s.toString().substring(0, s.length()-1) + "a");
txtfreak.setSelection(txtfreak.getText().length());
}else{
freaktext=freaktext+"a";
}
}
txtfreak.removeTextChangedListener(whateveryourlistenername);
if(s.toString().charAt(s.length()-1) != 'a'){
freaktext=freaktext+s.toString().charAt(s.length()-1);
txtfreak.setText(s.toString().substring(0, s.length()-1) + "a");
txtfreak.setSelection(txtfreak.getText().length());
}else{
freaktext=freaktext+"a";
}
txtfreak.addTextChangedListener(whateveryourlistenername);

Categories