Android Strings issue - java

My program produces a list of Strings in one activity, then passes it to another activity, and the second activity uses the strings.
When I test by printing out each element of the list at the beginning of the second activity, the printout looks perfect. For example, if I am hoping for the list to contain "Lemon Juice", it prints out exactly right, but yet the logic in the second activity still doesn't work. If I add "Lemon Juice" just like that to the list manually, the logic in the second activity works fine, so the issue is that somehow the string in the received List is not really "Lemon Juice". But:
It prints out exactly correctly (including checking for spaces in front and at the end).
I have tried explicitly casting the received list elements as (String) just to be sure they are Strings.
If I run "Lemon Juice".contains(received String) it comes back true, and if I run received String.contains("Lemon Juice") it
comes back true, but if I run received String.equals("Lemon Juice") it comes back false. This is very confusing to me.
Can anyone think of a possible explanation for how something that is cast as a string, prints as a string, and looks like a string, is not performing like a string?
EDIT to include some code as requested:
// instance variable at top of class--list to which strings will be added for use in
// 2nd activity
private List<String> exs = new ArrayList<String>();
// get array of strings from extra from intent from first activity
String[] recExs = getIntent().getStringArrayExtra(BrowseActivity.EXS);
for (int exx = 0; exx < recExs.length; exx++) {
String curEx = (String) recExs[exx];
exs.add(curEx);
}
Somehow, when I pass exs to the method I need to use the strings, it doesn't work, even though, as explained above, printing and calling contains etc all show that the string, before I added it to exs, was at I wanted it to be.

It's hard to help when you only posted a small snippet of your code.
But I'm guessing the reason String.contains works but String.equals doesn't is that maybe there is space in the Strings. Try String.trim on both side of the Activity when passing and receiving data.

Related

Java - A loop in a loop and the format gets lost

I'm French so excuse my English not necessarily correct.
I explain the context, I currently have a String array list named "tempCustomerDrugsIdsList" (var1) and another string array list named "tempDrugsTableList"(var2).
When I make a loop "For" on "var1" then another one in "var2","var2" loses its format, i. e. upper case is replaced by lower case and spaces are deleted.
I tested with another loop with the same type of variables (but empty), the result being the same I think the problem comes from my way of using java. Being on vb. net before, I must have taken some bad habits !
I don't know how to solve this problem, I've only been working in java for 2 weeks.
Thank you for helping me.
[EDIT]
My problem was:
List<String[]> tempDrugsTableList = otherList;
But this code doesn't duplicate the list.
AxelH gave me the following solution:
List<String[]> tempDrugsTableList = new ArrayList<String[]>(otherList);
Well, you are not doing a "copy" of the list
tempDrugsTableListCopy = tempDrugsTableList; // Get copy of original tempDrugsTableList for comparate
but sharing the reference, every update done in the tempDrugsTableListCopy will be done in the original list (same reference, same adress in memory). Since you are updating that copy in the following loops ... you update the original list too. What you want is to clone the list.
You could do it simply with copyList = new ArrayList(originalList); or for a deep clone, you need to iterate each element to duplicate those. (array need to be duplicated too if you change the value in those)
"String[]" tmpCustomerIds means you are getting a string array from a string array, which you would be using in a 2d array. Try it with just "String" in the for each loops. I am assuming you are using 1d arrays in this case.

Two issues with libgdx List widget

I am trying to use the libgdx List widget to make a list of all the items in an arraylist. Well, actually my arraylist is a list of objects, and each of the objects contains a string that is the objects "name".
However, when I try to show these with a List, it lists them horizontally, not vertically. If I try to show the contents of a normal array it lists the contents vertically. I am implementing Screen in my classes.
For example,
ArrayList<String> PartyListEntries = new ArrayList<>();
private List PartyList = new List(skin);
PartyListEntries.add("ham");
PartyListEntries.add("hag");
PartyListEntries.add("ham");
PartyList.setItems(PartyListEntries);
table.setFillParent(true);
table.top().left().padTop(10).padLeft(10);
table.add(PartyList);
stage.addActor(table);
This shows: [ham, hag, ham]
But if I make a String array and have the array contents be { "ham", "hag", "ham" }
then it shows
[ham]
[hag]
[ham]
horizontally(without the line breaks).
This is my first issue with list. My 2nd issue is that when string values are the same, it selects both of them. In the 2nd example, if I set the default selection to index zero it will put both index 0 [ham] and index 2 [ham] as selected. It will do this for every string that has the same value as whatever is selected. I.. don't want it to do this. I want them to be treated as unique since they are.
I am trying to look at the code for List but to be honest it's kind of beyond me. I don't know what causes these problems. I could really try to figure it out and I might and it will take me a long time, but I figure maybe you guys already know what is causing this. Or maybe can just offer me a good alternative to List.
Thanks!
Regarding the first question: the Libgdx widget just uses the toString method of whatever object you give it to make the text label. So that's why you get different results with lists and String arrays. It was just the preference of whomever wrote each of those classes how to format the array to a String. If you want to use the List class, you could subclass it and change the toString method to the way you want it, or you could create a List wrapper class that does its own method of converting the list to a String.
Regarding the second question: This is a peculiarity of Java. If you hard code strings (put them in your actual code in a class with quotation marks), then the compiler makes all matching strings into a single shared instance of the String class. So "ham" and "ham" are the same instance of String, the same object.
You can get around this by wrapping your string with a String constructor like this. new String("ham"). This will force it to create a separate instance of String.
Example:
String s0 = "a";
String s1 = "a";
String s2 = new String("a");
boolean b0 = s0.equals(s1); //evaluates true
boolean b1 = s0.equals(s2); //evaluates true
boolean b2 = s0==s1; //evaluates true
boolean b3 = s0==s2; //evaluates false
If you load your strings in from a file at runtime, matching strings will be different instances.

Testing for mutually exclusive correct assertions

I have a loop in my code which goes over a set of strings. Said strings are then passed along to several other functions.
In my tests, I'm basically emulating the flow of code and asserting at the start of each method I expect it to visit, if the string is correct.
But I can only write the test method once. Meaning that I have to do the following to catch all the different strings:
assertTrue(string.equals("test1") || string.equals("test2") || string.equals("test3") || ...);
However, there's a problem with this if one or more of those strings are not successfully passed to the list that is looped over. Since this is a chain of OR statements, it will succeed as long as there is 1 correct string, regardless of whether any of the other strings are missing. Which is a problem.
I can't emulate the loop, I can only emulate the functions receiving the data each time.
Is there a way to deal with this problem?
EDIT: some clarification.
I start out with a list of strings.
This list gets looped over, meaning every single string instance will go through a bunch of functions. And then the next string. And so on.
In the test, I can write dummies for the methods the string goes through. This means I override the behavior of the actual code and send my own custom return. This has to be correct though, since the function following that has to properly process what I just send to it.
But, when I start the test with the dummy data, it will do the loop, meaning the same function gets called multiple times, each time with a different string. I can't just do 1 test for one of the strings, because the next loop will fail on the next string.

Manipulating Strings on Arrays

I'm still new to Java and I would like to understand Strings and Arrays so I got this idea of manipulating elements and place them according to my objective. The objective is that there will be Array of Strings "ABBCCCBBAA" and the "AA","BB" must be replaced into "A" , "BA","AB" into CC. "CC","BC" into B. I basically have no idea how to make it happen but I know it must have Arrays of String. Please help
Regular expression can be very handy for you. Code bellow can do, your job with the use of regular expression:
String mainStr = "ABBCCCBBAA";
Pattern p = Pattern.compile("(AA)|(BB)|(BA)|(AB)|(CC)|(BC)");
Matcher m = p.matcher(mainStr);
while (m.find()) {
String matchedStr = m.group(0);
if("AA".equals(matchedStr) || "BB".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"X");
}
else if("BA".equals(matchedStr) || "AB".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"Y");
}
else if("CC".equals(matchedStr) || "BC".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"Z");
}
}
mainStr = mainStr.replaceAll("X","A").replaceAll("Y","CC").replaceAll("Z","B");
System.out.println(mainStr);
Above code will handle your case of multiple occurrence of same pattern in a given string like:
ABBCCCBBAABBBBAA
will generate output:
CCBBAAAAA.
I am assuming that by "array of strings" you mean:
String[] myvariable = new String[number];
myvariable[0] = "ABBCCBBAA";
myvariable[1] = "some_other_string";
If you are new to Java I suggest you read a beginner's book like Head First Java and also look into java documentation; you don't even have to go that far if you are programming with a decent IDE, like Netbeans (thanks to its intelli-sense feature) is a source of documentation for what you seek (meaning that you can look at all the methods available for a string, read what they do, and see if they can help accomplish what you need).
I am assuming (from what you have said) that you want to replace "AA" for "A", and from that result replace "BB" for "BA", and from that result replace "AB" into "CC", and from that result "BC" into "B".
The code I am posting is REAL simple, and it will only work for this particular case (as I have understood it), if you want to create a method that does this for any string, you need to change some things, but I'll leave that to you.
String[] yourArrayOfStrings = new String[1];
yourArrayOfStrings[0] = "ABBCCBBAA";
String resultOfReplacement= yourArrayOfStrings[0].replaceFirst("AA", "A");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("BB", "BA");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("AB", "CC");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("BC", "BB");
System.out.println(resultOfReplacement); //debugging purposes
The only reason why I created a String[] was because that's what you stated in your question, otherwise I would have simple created a String variable like I did with resultOfReplacement. To access the first element in an array you do arrayVariable[index]. Here I use the replaceFirst function that comes with Java for variables of type String. If you look the method up, it'll tell you that it will look for the first match of the first parameter and replace it with the second parameter.
The System.out.println I have added are for debugging purposes, so you can see on the console what is clearly happening with each replacement. So, the first time I call replaceFirst(...) on the original string which is a[0].
This will happen:
The method will look in "ABBCCBBAA" for the FIRST AND ONLY THE FIRST time "AA" appears and replace it with "A". The result is "return" and you must assign it to a variable if you want access to it to do more actions upon it. In this case, I assign it to a new String variable. You could have just assigned back to a[0], which is likely what you want. (You'd do so like this: a[0]=ourArrayOfStrings[0].replaceFirst("AA", "A");)
For the second replacement, the method will look in "ABBCCBBA" for the first time "BB" appears and replace it for "BA".
See the pattern? This is just a start, and depending on what you want you might need other methods like replaceAll().
Most IDEs will tell you what methods are available for a variable when you access it via ".", so that when you are typing " variablename. " right at that moment a list of methods available for it should appear, if they donĀ“t you can go ahead and do a shortcut like ctrl+space for it to appear and navigate through the methods via the arrow keys so you can read what they do (at least for Eclpise and Netbeans, while programming in Java, it works). Documentation is power!

why this code about combobox doesn't work?

I have a combobox which stores "Computer ,Code:21","History ,Code:31" and also the number of items can be changed.but when I write this code for getting its items:
List<String> bIHELessons = new ArrayList<String>();
for (int i=0;i<jComboBox1.getItemCount();i++) {
String lessons = (String) jComboBox1.getItemAt(i);
if (lessons != null&& lessons.trim().length()!=0) {
bIHELessons.add(lessons);
System.out.println(bIHELessons.toString());
}
}
it will show these sentences in the console:
[Computer,Code=21]
[Computer,Code=21, History,Code:31]
Because you are appending to the list with bIHELessons.add(..). Each subsequent call adds on to the already printed string.
If you want to still add to the ArrayList and print the current item that is in the ArrayList, then use System.out.println(bIHELessons.get(i)); rather than using what you are now. I also don't think you need to use toString() because your objects are already in the type string.
Change System.out.println(bIHELessons.toString()); to System.out.println(lessons); if you only want to print the string you are currently iterating on.
From what I can see your code is doing what it should be doing. Are you wanting to know why you are seeing all items repeated with each additional call to the print screen?
That is happening because the toString() method of the List is putting all the items in the list into a single string.
I don't think the problem is with JComboBox but rather with your expectations. System.out.println(bIHELessons.toString()); will print out the entire contents of the bIHELessons ArrayList. Since you're adding a new String to the ArrayList on each iteration, it's logical that your System.out.println(bIHELessons.toString()); would show a progressive accumulation of content.
Your question isn't clear but you may consider moving the System.out.println outside of your loop and determining if that's what you're looking for.
You are printing out the ToString() representation of your entire list. If you want to print out the object you could just print out the lessons variable instead.

Categories