string tokenizing from textview - java

I have TextView with text that changed dynamically.
i want tokenizing this text with delimiter space " " and send to another textview
this is my code
public void onClick(View v) {
// TODO Auto-generated method stub
if (v.getId()==R.id.button5){
Intent i = new Intent(this, Tokenizing.class);
String test = ((TextView)findViewById(R.id.textView6)).getText().toString();
String result = null;
StringTokenizer st2 = new StringTokenizer(test," ");
while (st2.hasMoreTokens()) {
String st3 = st2.nextToken();
System.out.println(st3);
result = st3;
}
i.putExtra("result", result);
startActivity(i);
Log.i("Test Klik Next", result);
but i have just last word in the textview.
text before tokenizing:
Examples of paradoxes can be humorous and confusing
text after tokenizing:
confusing
where is the part of my coding is wrong?

You are overwriting the result every time you read a new token
result = st3;
So it's always equal to the last value. Change the type of result from String to StringBuilder and just build it as you go
result.append(st3 + " "); //re-adding the space as the StringTokenizer will remove it
Then after the StringTokenizer loop just get the built String using result.toString()
Why not result += st3?
Some other answers suggest you do this. The reason not to do this is that in Java, String is immutable. This means they can't be changed so any time you append two String objects, a new String object is created.
So every step through the loop you are creating a new String object which is inefficient and unnecessary. StringBuilder is not immutable and Strings can be appended to it without the overhead of creating new objects every time.
StringTokenizer
Worth noting -as #RGraham said in the comments- that this class is deprecated. This means it's no longer in common use, use of it is discouraged and it could be removed at some point.
More information here.
Tokens - in or out
As other answers assumed the opposite of me and after discussion on one of said answers and on meta, I feel I need to clarify this. I
'm not sure if your intention was to get rid of the tokens (in this case spaces " ") and end up with
Examplesofparadoxescanbehumorousandconfusing
or to replace them when outputting the final String and get out what you put in. So I assumed you wanted to preserve the original meaning and replace them. Otherwise a quicker way to get the result above would be to simply skip all the tokenizing and do
test.replaceAll(" ","");

while (st2.hasMoreTokens()) {
String st3 = st2.nextToken();
System.out.println(st3);
result = st3; // Everytime you are reassigning result to some other String
}

Replace
result = st3; by (initialize String result=" ";)
result+=st3+" "
and then replace
i.putExtra("result", result); with i.putExtra("result", result.trim());
Try this , it will show perfect result.
You can also do this result.append(st3+" "); and then i.putExtra("result", result.trim());

Related

Check exact word in scrabble words list

I have a Scrabble Clock with a verification tool inside.
The verification word space looks in green or red if the word that I check is in the list.
The thing is, if I use sbuffer.toString().contains, and write a word like ABA, the word space looks in green though ABA is not in the list, but ABAC, ABACA are in the list.
I would like to know how I can implement a condition in my code to check the exact complete word.
I've researched regex, boundary and matches, but I couldn't find a line code that words in my code.
Here is my code until now.
public class MainActivity extends AppCompatActivity {
TextView textView;
TextView textInV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.texto_1);
textView.setMovementMethod(new ScrollingMovementMethod());
textInV = findViewById(R.id.textIn);
String data = "";
StringBuffer sbuffer = new StringBuffer();
InputStream is = this.getResources().openRawResource(R.raw.fruits);
BufferedReader reader = new BufferedReader((new InputStreamReader(is)));
if (is != null)
{
try
{
while((data =reader.readLine())!=null)
{
sbuffer.append((data + "\n"));
}
is.close();
}
catch (Exception e){ e.printStackTrace();}
}
textView.setText(sbuffer);
}
}
The contains method on a string tests whether the target is contained as a substring; if ABAC is contained as a substring then so is ABA, since ABA is a substring of ABAC and hence it is also a substring of any string which ABAC is a substring of. Therefore, it is not logically possible for the String.contains method to return true for ABAC and false for ABA.
You want to test if the target is one of the elements of a collection of strings, so you should use contains on a collection of strings, not on a string. The best choice is a HashSet, since this performs membership tests in O(1) time on average.
> import java.util.*;
> Set<String> allowed = new HashSet<>();
> allowed.add("ABAC");
> allowed.add("ABACA");
> allowed.contains("ABA")
false
> allowed.contains("ABAC")
true
As #Ashutosh KS has already mentioned, String.contains is not really what you are looking for in this case: You want to check if two strings are identical, not if one contains the other.
The Java String class contains a few methods that you can use to compare the content of two strings, of which you can choose accordingly to match your exact use case:
contentEquals(CharSequence cs) and contentEquals(StringBuffer sb) both check if the passed string representation's content matches the current one.
equals(Object str) is similar to contentEquals in that it makes an exact comparison between both strings, however it also checks to make sure that the passed object is in fact a string.
equalsIgnoreCase(String anotherString), as the name implies, will do a check while ignoring the string case.
These are the 'proper' ways to compare two strings exposed by the native API, so while it is absolutely possible to use other methods, it is a good idea to stick to these.
StringBuffer's contains() check if the given string is a substring of the text in the sbuffer. That means, it will output true for searching "ABC" in "ABC", "ABCBC", "ZABC", "ZABCBC"...
If you want to search for a complete word in the sbuffer, then you can look for "\n" + "ABC" + "\n" since you're adding "\n" when adding words to sbuffer: sbuffer.append((data + "\n"));. But, you must also initialize sbuffer with "\n": StringBuffer sbuffer = new StringBuffer("\n");.
sbuffer.toString().contains("\n" + "ABC" + "\n"); // this will do the trick
Test code:
class Main {
public static void main(String[] args) {
StringBuffer sbuffer = new StringBuffer("\n");
StringBuffer sbuffer2 = new StringBuffer("\n");
sbuffer.append("ABC" + "\n");
sbuffer.append("ABCBC" + "\n");
sbuffer.append("ZABC" + "\n");
sbuffer.append("ZABCBC" + "\n");
System.out.println("Is ABC in sbuffer = " + sbuffer.toString().contains("\n" + "ABC" + "\n"));
sbuffer2.append("ABCBC" + "\n");
sbuffer2.append("ZABC" + "\n");
sbuffer2.append("ZABCBC" + "\n");
System.out.println("Is ABC in sbuffer2 = " + sbuffer2.toString().contains("\n" + "ABC" + "\n"));
}
}
Test output:
Is ABC in sbuffer = true
Is ABC in sbuffer2 = false
Now i have this, and works, but i have a file with the words, and i would like to add the files in the diccionario.
But i don't know how to read the file. I have try bufferread, but i need try/catch, and not works....
Some other solutions....
Thanks
boton2.setOnClickListener(new View.OnClickListener()
{
String content;
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onClick(View view)
{
HashSet<String> diccionario = new HashSet<String>();
//Adding elements to HashSet
diccionario.add("CASA");
diccionario.add("ABAC");
if(diccionario.contains(textIn.getText().toString().toUpperCase()))
{
textIn.setBackgroundColor(Color.GREEN);
}
else
{
textIn.setBackgroundColor(Color.RED);
}
}

Why string concatenation takes so long time? [duplicate]

This question already has answers here:
StringBuilder vs String concatenation in toString() in Java
(20 answers)
Closed 7 years ago.
I am concatenating a String in a loop but it takes ages, why is that?
for (String object : jsonData) {
counter++;
finalJsonDataStr += object;
}
Variable object is a piece of JSON, up to 70 chars and the loop goes approx 50k times.
I understand some people advice StringBuffer or StringBuilder but this link says, it has no performance improvements: StringBuilder vs String concatenation in toString() in Java
Use a String Builder to append to strings.
When you concatenate, Java is actually creating a new String with the results of the concatenation.
Do it multiple times and you are creating gazillion of strings for nothing.
Try:
StringBuilder sb = new StringBuilder();
for (String object : jsonData) {
counter++;
sb.append(object.toString()); //this does the concatenation internally
//but is very efficient
}
finalJsonDataStr = sb.toString(); //this gives you back the whole string
Remark:
When you do stuff like
myString = "hello " + someStringVariable + " World!" + " My name is " + name;
The compiler is smart enough to replace all that with a single StringBuilder, like:
myString = new StringBuilder("hello ")
.append(someStringVariable)
.append(" World!")
.append(" My name is ")
.append(name).toString();
But for some reason I don't know, it doesn't do it when the concatenation happens inside a loop.
You should use a StringBuffer or a StringBuilder.
When you add Strings with plus, a StringBuilder is created, strings are concatenated and a new String is return with toString() method of the StringBuilder. So image this object creation and string manipulation 50k times. It's much better if you instantiate only one StringBuilder yourself and just append strings...
This answer could be of use to you: concatenation operator (+) vs concat()
Before going to the actual problem, see how internal concatenation works.
String testString ="str"+"ingcon"+"catenation";
If we print the above declared String to console and see, the result is stringconcatenation.Which is correct and the + works fine. Here is out actual question, how does that + symbol did the magic ? ? Is it not a normal mathematical addition of Strings. The below code snippet shows how that code with + actually converts.
StringBuilder compilerGeneratedBuilder = new StringBuilder();
compilerGeneratedBuilder.append("str");
compilerGeneratedBuilder.append("ingcon");
compilerGeneratedBuilder.append("catenation");
String finalString = compilerGeneratedBuilder.toString();
More .....
50K times loop is a descent performance blocker to consider.
In such cases use StringBuilder with append method. Cause concat (+) create a new object every time a new String Builder object. That leads to 50k objects creations.
With single StringBuilder and append method, you can save the time of Objection creation as well as the memory too.

Removing punctuation is not working in Java with string replacement

So, what I'm trying to do is compile a single word list with no repeats out of 8 separate dictionary word lists. Some of the dictionaries have punctuation in them to separate the words. Below is what I have that pertains to the punctuation removal. I've tried several different solutions that I've found on stack overflow regarding regex expressions, as well as the one I've left in place in my code. For some reason, none of them are removing the punctuation from the source dictionaries. Can someone tell me what it is I've done wrong here and possibly how to fix it? I'm at a loss and had a coworker check it and he says this ought to be working as well.
int i = 1;
boolean checker = true;
Scanner inputWords;
PrintWriter writer = new PrintWriter(
"/home/htarbox/Desktop/fullDictionary.txt");
String comparison, punctReplacer;
ArrayList<String> compilation = new ArrayList<String>();
while (i <9)
{
inputWords = new Scanner(new File("/home/htarbox/Desktop/"+i+".txt"));
while(inputWords.hasNext())
{
punctReplacer = inputWords.next();
punctReplacer.replaceAll("[;.:\"()!?\\t\\n]", "");
punctReplacer.replaceAll(",", "");
punctReplacer.replaceAll("\u201C", "");
punctReplacer.replaceAll("\u201D", "");
punctReplacer.replaceAll("’", "'");
System.out.println(punctReplacer);
compilation.add(punctReplacer);
}
}
inputWords.close();
}
i = 0;
The line
punctReplacer.replaceAll(",", "");
returns a new String with your replacement (which you're ignoring). It doesn't modify the existing String. As such you need:
punctReplacer = punctReplacer.replaceAll(",", "");
Strings are immutable. Once created you can't change them, and any String manipulation method will return you a new String
As strings are immutable you have to reset your variable:
punctReplacer = punctReplacer.replaceAll("[;.:\"()!?\\t\\n]", "");
(btw, immutable means that you cannot change the value once it has been set, so with String you always have to reset the variable if you want to change it)

What is the difference between a = a.trim() and a.trim()?

I've ran into a bit of a confusion.
I know that String objects are immutable. This means that if I call a method from the String class, like replace() then the original contents of the String are not altered. Instead, a new String is returned based on the original. However the same variable can be assigned new values.
Based on this theory, I always write a = a.trim() where a is a String. Everything was fine until my teacher told me that simply a.trim() can also be used. This messed up my theory.
I tested my theory along with my teacher's. I used the following code:
String a = " example ";
System.out.println(a);
a.trim(); //my teacher's code.
System.out.println(a);
a = " example ";
a = a.trim(); //my code.
System.out.println(a);
I got the following output:
example
example
example
When I pointed it out to my teacher, she said,
it's because I'm using a newer version of Java (jdk1.7) and a.trim()
works in the previous versions of Java.
Please tell me who has the correct theory, because I've absolutely no idea!
String is immutable in java. And trim() returns a new string so you have to get it back by assigning it.
String a = " example ";
System.out.println(a);
a.trim(); // String trimmed.
System.out.println(a);// still old string as it is declared.
a = " example ";
a = a.trim(); //got the returned string, now a is new String returned ny trim()
System.out.println(a);// new string
Edit:
she said that it's because I'm using a newer version of java (jdk1.7) and a.trim() works in the previous versions of java.
Please find a new java teacher. That's completely a false statement with no evidence.
Simply using "a.trim()" might trim it in memory (or a smart compiler will toss the expression entirely), but the result isn't stored unless you precede with assigning it to a variable like your "a=a.trim();"
String are immutable and any change to it will create a new string. You need to use the assignment in case you want to update the reference with the string returned from trim method. So this should be used:
a = a.trim()
You have to store string value in same or different variable if you want some operation (e.g trim)on string.
String a = " example ";
System.out.println(a);
a.trim(); //output new String is not stored in any variable
System.out.println(a); //This is not trimmed
a = " example ";
a = a.trim(); //output new String is stored in a variable
System.out.println(a); //As trimmed value stored in same a variable it will print "example"

Concatenate a new string at the beginning of an existing string

i want to concatenate a new string to the start of an existing string, for example,
the current string="" and i want always to concatenate the new string to start of my old string:
String msg="Java One",temp;
for(int i=msg.length()-2;i>0;i--){
here i make a loop starting from the end of msg after the end finishes temp should contains "Java One" but in this order
e
ne
one
a one
va one
}
and so on
I want always to concatenate the new string to start of my old string
This is very simple, but not very efficient:
String oldString = "";
for (...) {
// Prepare your new string
String newString = ... ;
// Add the new string at the beginning of the old string
oldString = newString + oldString;
}
You can use String#substring(int,int) to get different substrings in each iteration.
for(int i=msg.length()-1;i>=0;i--){
System.out.println(msg.substring(i,msg.length()));
}
Of course you can store each generated substring and do what you wish with it.
Note that this approach is likely to be more efficient, because though new String objects will be created, it is likely to use the same underlying char[] object for all of them.
Also note that we are iterating from msg.length()-1 (and not -2, as the original code in the question) and while i >= 0 (and not i > 0, as in the original question)

Categories