Why this if statement is being skipped? - java

Can anyway tell me why the following if statement is being skipped?
I want to check if my mAlphabetCode contains 0-9 literal, not 0 to 9.
// check if alphabet code is numeric
if (mAlphabetCode.equals("0-9")){
mAlphabetCode = "-";
}
Here is the whole code:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.lv_gl_content) {
// store data to be pass
Intent mIntent = new Intent(this, AchList.class);
mIntent.putExtra("mPageUrl", mGameList.get(position).getItemPageUrl());
mIntent.putExtra("mGameTitle", mGameList.get(position).getTitle());
// start activity and page animation
startActivity(mIntent);
mPageTrans.slideIn();
} else if (parent.getId() == R.id.lv_alphabet_content) {
// get alphabet code
String mAlphabetCode = parent.getAdapter().getItem(position).toString().toLowerCase();
// check if alphabet code is numeric
if (mAlphabetCode.equals("0-9")){
mAlphabetCode = "-";
}
// build page url
mGameListUrl = mGameListUrl.substring(0, (mGameListUrl.length() - 2) ) + mAlphabetCode + "/";
mAlphabetMenu.setItemChecked(position, true);
// close browsing menu
mSlidingPane.closePane();
// make network request
mStringRequest = new StringRequest(Request.Method.GET, mGameListUrl, onSuccess(), onError());
mRequestQueue.add(mStringRequest);
}
}
And here is what the debugger saying that mAlphabetCode contains before hitting the if statement:
My error was here in my strings.xml file:
<!-- strings of arrays -->
<string-array name="slide_menu_alphabet">
<item>0–9</item>
I had changed the item from 0-9 to 0 &#8211 ;9 (spaced so numbers show) as AndroidStudio IDE subjected and thanks to #user1873880 and David Cesarino, I changed to 0 &#45 ;9 (spaced so numbers show) and now it works great.
Thanks for the help.

The problem is that '-' character in your code is in fact has integer number 45, while in the debugger it's 8211, which mean that it is different character. You can verify this via some logs, just try to see this value (int) '-'.

Related

Decimal points in calculator android

I am creating a calculator app in android. The issue is how can I check for existence of two decimals in a single numeric value . Currently my calculator allows inputs such as 1.2.3 which is illegal . It must allow a decimal if an operator has been used. Eg 1.1+2.2 is legal but 1.1.1+2.2 isn't.
Here is my code for decimal handling:
public class TrialCalculator extends AppCompatActivity implements Button.OnClickListener {
Button btn1, btn2, btnBack, btn3, btn4, btn5, btn6, btn7, btn8, btn9, btn0, btnPlus, btnMinus, btnMul, btnDiv, btnEquals, btnClear, btnDecimal, btnPercent;
EditText calcResult;
double number = 0;
private char opcode = '1';
private void handleDecimal() {
if (opcode == 0) clear();
if (calcResult.getText() == null) {
calcResult.setText("0.");
calcResult.setSelection(2);
} else {
String txt = calcResult.getText().toString();
if (txt.lastIndexOf(".")<txt.length()-1) {
calcResult.append(".");
}
}
}
}
I am calling the buttonDot from onClick Method.
One solution is to have a flag which keeps track of the decimal:
class MyCalculator {
private hasDecimal = false;
// ...
}
Set this flag to true the first time that the user types a decimal. Then check the flag to see if a decimal has been previously typed.
Of course, this only works if you are responding to each key press directly rather than getting the entire input from a EditText after the user has typed the entire number.
You can use regex with matches function
\\d* mean match zero or more digits
(\\.\\d+)? match a . followed by one or more digits , ? mean matches between zero or one times of given group
Regex Demo : note with matches function in java, we don't need ^ start and $ ending anchors
Code
if (txt.matches("\\d*(\\.\\d+)?")) {
// number has one decimal
}
else{
// number has more than one decimal
}
Note: if you don't want to allow values like .5 then use \\d+ instead of \\d* as
\\d+(\\.\\d+)?
As suggested by #Code-Apprentice , if you want to accept values like 4343. etc
you can use
\\d*(\\.\\d*)?
Using text watcher
calcResult.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void afterTextChanged(Editable s) {
boolean flag = s.toString().matches("\\d*(\\.\\d*)?");
if(!flag){
// calcResult.setError...
// you display a toast
}
}
});
Update : To match multiple values with operators , you can use
(\\d*(\\.\\d*)?([+\\-*%\\]|$))*
RegEx demo
Test Cases
String pat="(\\d*(\\.\\d*)?([+\\-*%\\]|$))*";
System.out.println("4.5-3.3+3.4".matches(pat));
System.out.println(".5".matches(pat));
System.out.println("4".matches(pat));
System.out.println("4.5.5-4.4".matches(pat));
System.out.println("4.44.5+4.4.4".matches(pat));
System.out.println("4.".matches(pat));
Output :
true
true
true
false
false
true
lastIndexOf returns -1 if the character is not found in the string. So your condition txt.lastIndexOf(".")<txt.length()-1 is always true. You could change it to
txt.lastIndexOf(".") == -1
To check for existence of two decimals in a single no then split the string by decimal.
for e.g.,
String txt = calcResult.getText().toString();
String[] decimals = txt.split("\\.");
if(decimals.length > 2) {
// txt contains more than 1 decimal.
// Your logic ..
}

Making a substring out of a line read from file

So I am trying to read through a .txt file and find all instances of html tags, push opening tags to a stack, and then pop it when I find a closing tag. Right now I am getting String out of bounds exception for the following line:
if(scan.next().startsWith("</", 1))
{
toCompare = scan.next().substring(scan.next().indexOf('<'+2), scan.next().indexOf('>'));
tempString = htmlTag.pop();
if(!tempString.equals(toCompare))
{
isBalanced = false;
}
}
else if(scan.next().startsWith("<"))
{
tempString = scan.next().substring(scan.next().indexOf('<'+1), scan.next().indexOf('>'));
htmlTag.push(tempString);
}
It is telling me that the index of the last letter is -1. The problem I can think of is that all of the scan.next() calls are moving onto the next string. If this is the case, do I need to just write
toCompare = scan.next()
and then so my comparisons?
You have two major problems in your code:
you're calling scan.next() way too much and as you expect, this will move the scanner to the next token. Therefore, the last one will be lost and gone.
.indexOf('<'+2) doesn't return the index of '<' and adds 2 to that position, it will return the index of '>', because you're adding 2 to the int value of char < (60; > has 62). Your problem with index -1 ("It is telling me that the index of the last letter is -1.") comes from this call: .indexOf('<'+1) this looks for char '=' and if your string doesn't contain that, then it will return -1. A call for #substring(int, int) will fail if you pass -1 as the starting position.
I suggest the following two methods to extract the value between '<' and '>':
public String extract(final String str) {
if (str.startsWith("</")) {
return extract(str, 2);
} else if (str.startsWith("<")) {
return extract(str, 1);
}
return str;
}
private String extract(final String str, final int offset) {
return str.substring(str.indexOf('<') + offset, str.lastIndexOf('>'));
}
As you can see, the first method evaluates the correct offset for the second method to cut off either "offset. Mind that I wrote str.indexOf('<') + offset which behaves differently, than your str.indexOf('<' + offset).
To fix your first problem, store the result of scan.next() and replace all occurrences with that temporary string:
final String token = scan.next();
if (token.startsWith("</")) { // removed the second argument
final String currentTag = extract(token); // renamed variable
final String lastTag = htmlTag.pop(); // introduced a new temporary variable
if (!lastTag.equals(currentTag)) {
isBalanced = false;
}
}
else if (token.startsWith("<")) {
htmlTag.push(extract(token)); // no need for a variable here
}
I guess this should help you to fix your problems. You can also improve that code a little bit more, for example try to avoid calling #startsWith("</") and #startsWith("<") twice.

String comparison not working as intended. I want to compare two String values but the comparison always seems to give a true result

I am fetching column values from my DB (Which is working fine) then I am putting these values into 'String X' one at a time as it loops. In the same loop I want to compare the values supplied to me by the user through UI with X and based on this comparison I want x to be true or false. But x always shows true! Here is my code:
private boolean fillData() {
Cursor c = DBHelper.fetchAllIDs();
// List<String> idList = new ArrayList<String>();
if (c.moveToFirst()) {
do {
String X = (c.getString(c.getColumnIndexOrThrow("IDno")));
Toast.makeText(getApplicationContext(), "" +X, Toast.LENGTH_LONG).show();
String B = null;
B = Idno.getText().toString();
if (B.equals(X));
{
Toast.makeText(getApplicationContext(), "If condition true"+B, Toast.LENGTH_LONG).show();
x=true;
}
} while (c.moveToNext());
}
return x;
}
Try to print the value of
String X = (c.getString(c.getColumnIndexOrThrow("IDno")));
such as Sop(x) or inside log.
and same way print the value of
B = Idno.getText().toString();
Sop(B) or inside log(B).
It may be both are same in meaning but different in present (case sensitive).
use
if(B.equalsIgnoreCase(X))
{
}
instead of if (B.equals(X));
don't put the condition termination symbol such as ; at end of if statement.
I got this folks, I had mistakenly put a ';' at the end of my if statement. Sorry! Silly!

ArrayIndexOutOfBoundsExecption:Android

I am a newbie Android Developer. I am trying to get a text input from user using and Edittext box and then convert that text into string and then into a char array of size 4. i have an array already stored that is of size 4 and it contains values. i want to compare both the arrays and perform a task based on the result.
I don't know why am i getting the ArrayIndexOutOfBoundsExecption
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newgame);
Button submit = (Button) findViewById(R.id.guess);
EditText guess = (EditText) findViewById(R.id.editText1);
boolean c=false;
char[] guessword;
char[] appword = {'T', 'R', 'U', 'E'};
guessword = guess.getText().toString().toCharArray();
for(int i=0;i<appword.length;i++)
{
if(guessword[i]==appword[i])
{
c=true;
}
else
{
c=false;
}
}
final boolean correct=c;
submit.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(correct){
startActivity(new Intent(Newgame.this, Win.class));
}
else{
startActivity(new Intent(Newgame.this, Loose.class));
}
}
});
}
}
The problem is that guessword may have fewer than four characters, and your code does not check for that condition.
Change your code as follows to account for this condition:
for(int i=0;i<appword.length;i++)
{
if((i < guessword.length) && (guessword[i]==appword[i]))
{
c=true;
}
else
{
c=false;
break; // <<<=== Add this to end the loop
}
}
Also note that your code as written does not "lock in" the false when characters are not equal to each other: for example, {'A','B','Z'} and {'X', 'Y', 'Z'} will compare equal under your old algorithm. Add break to exit the loop as soon as you see a false.
This is because you are going with the index from 0 to the value of the appword.
Take for example the case in which the user types in: "NO". Because you are iterating over appword which has the length greater than your actual text, when you do a guessword[i] it will crash throwing your IndexOutOfBoundsException.
I am not sure why you are using char[]. As I can see, for your example, String could solve the problems.
String appword = "TRUE";
String guessword = guess.getText().toString();
Then, the method that shows if the 2 are equal is :
if (appword.equals(guessword))
If you also want to match the case, use equalsIgnoreCase instead.
guessword is null when you walk over the first time (which happens in the onCreate). One thing you could do is change
if(guessword[i]==appword[i])
to
if(guessword != null && guessword.length =< i && guessword[i]==appword[i])
If you just want to compare the entered text to "TRUE", you can simply do:
String guessword = guess.getText().toString();
if ("TRUE".equals(guessword)) {
...
}

comparison with strings having white space

Sorry if it's a silly question. I need to compare with a name which has three words separated by one white space. If the name is null or "This is Android" i would do something, otherwise i do something else. For example, is the following code right to do this comparison?
if((name==null)||(name.equalsIgnoreCase("This is Android")))
{
//start activity 1
}
else
{
//start activity 2
}
"This is Android " is different from "This is Android" and equalsIgnoreCase will return false. You can use trim() to remove spaces and the start or the end of the Strings.
Hope this helps!
You should check if the name is null before you do that, otherwise it looks good. (except for, it should be if instead of If):
//either
if(name != null) {
if(name.equalsIgnoreCase("This is Android") {
}
}
//or
if("This is Android ".equalsIgnoreCase(name)) {
Update:
When you are comparing strings, the whitespaces count. So, basically "Hello world" and "Hello world " are not equal.
You need to use the .trim() method to ignore the surrounding whitespaces.
name = name.trim(); //since strings are immutable you need to assign return value to name
if("This is Android".equalsIgnoreCase(name)) {
Always keep constant String on left hand side in equals, this ensures no NPE:
like this :
if ("This is Android ".equalsIgnoreCase(str1)) {
// start activity 1
} else {
// start activity 2
}
In case you dont want space then add trim():
if ("This is Android ".trim().equalsIgnoreCase(str1)) {
// start activity 1
} else {
// start activity 2
}
if("This is Android".equalsIgnoreCase(name))
// start activity 1
} else {
// start activity 2
}
or the bullet-proof (in case user pasted value with unwanted spaces at the end of string)
if(name != null && "This is Android".equalsIgnoreCase(name.trim()))
// start activity 1
} else {
// start activity 2
}

Categories

Resources