Java check if something was added to a string - java

I periodically check if a string which I get from a web service changed. This works just fine but if an old string is deleted from my method triggers, too.
For Example:
//I get this at the beginning
"One,Two,Three"
//And at the next check I get this
"Two,Three"
So the String changed and my method returned true like it is supposed to do.
But I only want to return true if e.g. "Four" is added to the string.
Can anyone give me a solution for this problem?
Thank you a lot,
Freezed

if (!oldstring.contains(newstring)))
return true;

Perhaps you could use split like so
public class MyClass {
public static void main(String args[]) {
String oldString = "This,Is,A,Test";
String[] oldItems = oldString.split(",");
String newString = "This,Is,A,New";
String[] newItems = newString.split(",");
// For each new item, check all old items
for (String newItem: newItems)
{
Boolean foundItem = false;
for (String oldItem: oldItems)
{
// Item was already in the old items
if (newItem.equals(oldItem))
{
foundItem = true;
break;
}
}
// New item is not in the old list of items
if (!foundItem)
{
System.out.println("New item added: " + newItem);
}
}
}
}

Something like
newString.contains(oldString) && !newString.equals(oldString)

Why not just trigger when the length of the string increases? The question doesn't state that what is being added matters--only whether something is being added at all.
boolean result = false;
if(newString.length() > oldString.length()) {
result = true;
break;
}
return result;
EDIT: Based on further clarification, I understand that the length of the string is not the best indicator, since something can be removed and added at the same time, in which case OP wants true returned--even if length is shorter. Here's a solution that splits the strings into tokens, and then checks whether the last token of the old string occurs before the last token of the new string, because that means something was added after it:
boolean result = false;
String delim = ",";
String oldStringTokens[] = oldString.split(delim);
String newStringTokens[] = newString.split(delim);
for(int i = 0; i < newStringTokens.length; i++) {
if(oldStringTokens[oldStringTokens.length-1].equals(newStringTokens[i])) {
if(i < newStringTokens.length - 1) {
result = true;
}
}
}
return result;

Related

String.replace result is ignored?

So i'm using IntelliJ and the replace buzzword is highlighted. Most of the tips are over my head so i ignore them, but what i got for this one was that the result of string.replace is ignored. Why?
would i need something like ( string = string.replace(string.charAt(i));)?
import java.util.Scanner;
public class PhoneNumberDecipher {
public static String phoneNumber;
public static String Decipher(String string) {
string = phoneNumber;
for(int i =0; i<=phoneNumber.length(); i++) {
if(string.equalsIgnoreCase("A")
||string.equalsIgnoreCase("B")
||string.equalsIgnoreCase("C")) {
string.replace(string.charAt(i),'2')
}
else if(string.equalsIgnoreCase("D")
||string.equalsIgnoreCase("E")
||string.equalsIgnoreCase("F")) {
string.replace(string.charAt(i),'3');
}
else if(string.equalsIgnoreCase("G")
||string.equalsIgnoreCase("H")
||string.equalsIgnoreCase("I")) {
string.replace(string.charAt(i),'4');
}
else if(string.equalsIgnoreCase("J")
||string.equalsIgnoreCase("K")
||string.equalsIgnoreCase("L")) {
string.replace(string.charAt(i),'5');
}
else if(string.equalsIgnoreCase("M")
||string.equalsIgnoreCase("N")
||string.equalsIgnoreCase("O")) {
string.replace(string.charAt(i),'6');
}
else if(string.equalsIgnoreCase("P")
||string.equalsIgnoreCase("Q")
||string.equalsIgnoreCase("R")
|| string.equalsIgnoreCase("S")) {
string.replace(string.charAt(i),'7');
}
else if(string.equalsIgnoreCase("T")
||string.equalsIgnoreCase("U")
||string.equalsIgnoreCase("V")) {
string.replace(string.charAt(i),'8');
}
else if(string.equalsIgnoreCase("W")
||string.equalsIgnoreCase("X")
||string.equalsIgnoreCase("Y")
||string.equalsIgnoreCase("Z")) {
string.replace(string.charAt(i),'9');
}
}
return string;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Please Enter a Phone Number you Wish to Decipher...");
phoneNumber = input.nextLine();
System.out.print(Decipher(phoneNumber));
}
}
String objects are immutable.
From the docs:
public String replace(char oldChar,char newChar)
Returns a string resulting from replacing all occurrences of oldChar in this string with newChar.
Hope this helps.
IntelliJ is complaining that you're calling a method whose only effect is to return a value (String.replace) but you're ignoring that value. The program isn't doing anything at the moment because you're throwing away all the work it does.
You need to use the return value.
There are other bugs in there too. You might be able to progress a little further if you use some of this code:
StringBuilder convertedPhoneNumber = new StringBuilder();
// Your loop begins here
char curCharacter = phoneNumber.charAt(i);
if (curCharacter == 'a') {
convertedPhoneNumber.append("2");
}
// More conditional logic and rest of loop goes here.
return convertedPhoneNumber.toString();
I had the same problem, but i did it like this:
String newWord = oldWord.replace(oldChar,newChar);
use that statement
string = string.replace(string.charAt(i));
Why? String is an immutable object. Look at this thread to get a complete explanation. This a fundemental part of Java, so make sure you learn it well.
string = string.replace(string.charAt(i), '<The char to replace>') will work.
Refer to this article you might understand better:
https://alvinalexander.com/blog/post/java/faq-why-isnt-replace-replaceall-replacefirst-not-working/
Since string is immutable, you have to reassign the a string with the string.replace() string.

How to remove if else condition from loop?

I have a code snippet similar to the one below,
public ArrayList getReport(reportJDOList,accountType)
{
String abc = "";
for(ReportJDO reportJDO : reportJDOList)
{
if(accountType.equals("something")
abc = reportJDO.getThis();
else
abc = reportJDO.getThat();
//somecode goes here
}
returning List;
}
As I know the value of accountType before the iteration, I dont want this check to happen, for every entry in a list as it would cause numerous number of checks if the size of reportJDOList is 10000 for an instance. How we remove this thing from happening? Thanks in Advance :)
You can indeed peform check once and implement 2 loops:
if(accountType.equals("something") {
for(ReportJDO reportJDO : reportJDOList) {
abc = reportJDO.getThis();
}
} else {
for(ReportJDO reportJDO : reportJDOList) {
abc = reportJDO.getThat();
}
}
Obviously you can improve your design by either
separating you loops into 2 different methods
Using command pattern, i.e. implementing loop body in different command and executing it to loop.
Using Guava's Function (it is just improvement of #2)
Using java 8 streams.
IF you want to save the String comparison, make it once before the loop and store the result in a boolean variable :
String abc = "";
boolean isThis = accountType.equals("something");
for(ReportJDO reportJDO : reportJDOList) {
abc = isThis ? reportJDO.getThis() : reportJDO.getThat();
//somecode goes here
}
I'd vote for clean coding this - perform the check once and delegate the logic into private methods, each performing the loop individually. This duplicates code for the loop but gives greatest flexibility if at some point you need to do something more in SomethingReport that's not duplicated in OtherReport.
public ArrayList getReport(reportJDOList,accountType) {
if("soemthing".equals(accountType)) {
return getSomethingReport(reportJDOList);
} else {
return getOtherReport(reportJDOList);
}
}
private ArrayList getSomethingReport(reportJDOList) {
[...]
}
interface AccountHandler {
String get(Report r);
}
AccountHandler thisHandler= new AccountHandler() {
#Override
public String get(Report r) {
return r.getThis();
}
};
AccountHandler thatHandler= new AccountHandler() {
#Override
public String get(Report r) {
return r.getThat();
}
};
//...............
AccountHandler ah;
ah = (what.equalsIgnoreCase("this")) ? thisHandler : thatHandler;
Report r=new Report();
// loop
ah.get(r);
//Using reflection:
Report r = new Report();
Method thisMethod = r.getClass().getDeclaredMethod("getThis");
Method thatMethod = r.getClass().getDeclaredMethod("getThat");
Method m = (what.equalsIgnoreCase("this")) ? thisMethod : thatMethod;
m.invoke(r);

i want to get the character that a string is made of. for example if i have str=aabbc then the answer is abc

Here is the function i wrote. it take a Stringbuffer text then assign v[0]=text[0] , then starts from text[1] >>>text[n-1] the comparing. The vector v should contain the characters. I don't know where is the problem. Can you help me?
public void setdirectory(StringBuffer text)
{
String temp;
boolean t;
v.add(0,String.valueOf(text.charAt(0))); //A[0]=first letter in text.
for(int i=1;i<text.length();++i)
{
temp=String.valueOf(text.charAt(i));
try{
for(int j=0;j<v.capacity();++j)
{
if(!temp.equals(v.elementAt(j)))
{
v.add(i,temp);
}
v.trimToSize();
}
// System.out.println(v.capacity());
}catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("usage error");
}
}
}
If you're using Java 8+, then it might be simpler to use the new Stream API...
String str = "aabbc";
StringBuilder sb = new StringBuilder(str.length());
str.chars().distinct().forEach(c -> sb.append((char)c));
System.out.println(sb.toString());
Which prints
abc
I'd write a function to get unique characters, and assuming you need to preserve the insertion order, I'd use a LinkedHashSet<Character> and I'd prefer StringBuilder over StringBuffer. Something like
static String getUniqueCharacters(String text) {
Set<Character> set = new LinkedHashSet<>();
for (char ch : text.toCharArray()) {
set.add(ch);
}
StringBuilder sb = new StringBuilder();
for (char ch : set) {
sb.append(ch);
}
return sb.toString();
}
An alternative Java 8 solution is:
String str = "aabbc";
String str2 = str.chars().distinct().mapToObj(j->""+(char)j).collect(Collectors.joining());
System.out.println(str2);
Behind the scenes, this is similar to other answers here as IntStream::distinct is implemented using a LinkedHashSet<Integer>, and joining uses a StringBuilder.
You need to keep track of where you are adding your value in the vector. Also the number of objects in a vector is size(), not capacity() (look up the API for both; capacity() shows the current number of 'spaces' filled and available to fill before the vector needs to expand, it doesn't show how much of it has actually been filled).
Doh, and the third reason your code would not have worked: you were adding the character every time it found a non-matching one in the vector (over-writing itself each time so you would have only seen the last addition)
public void setdirectory(StringBuffer text) {
String temp;
boolean t;
int addAt = 0;
v.add(addAt,String.valueOf(text.charAt(0))); //A[0]=first letter in text.
for(int i=1;i<text.length();++i) {
temp=String.valueOf(text.charAt(i));
try {
boolean found = false
for(int j=0;j<v.size();++j) {
if(temp.equals(v.elementAt(j))) {
found = true;
break;
}
}
if (!found) {
addAt++;
v.add(addAt,temp);
}
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("usage error");
}
}
}
And although this would fix your code as it stands (which will be an important exercise for a beginner programmer), there are other ways of doing this that you should explore.

DeleteSubString in Java

I have written my own deleteSubString method as i'm experimenting creating all the java functions. However i'm having issues with the output it produces. Here is my code:
//deleteSubString
String subString = "ON";
String delString = "PONY";
String emp = "";
int delIndex = 0;
for(int i=0; i<delString.length()-1; i++){
if(delString.contains(subString)){
//do nothing
//read the rest of the string to confirm it contains
for(int j=delIndex; j<delString.length()-1; j++){
if(delString.contains(subString)){
//do nothing
}
else{
emp += delString.charAt(j);
}
}
}
System.out.println("Delete SubString");
System.out.println(emp);
}
What I expect to happen is the string to print out as "PY" but instead it chooses not to print anything at all. Any ideas would be greatly appreciated!
if(delString.contains(subString)){ is always true so emp is never set to a new String.
PONY contains ON and delString.length()-1 won't consider the last character,so your else part would not run.
Instead simply do
if(delString.contains(subString))
{
int delSize=subString.length();
int index1=delString.indexOf(subString);
int index2=index1+delSize;
return delString.substring(0,index1)+""+delString.substring(index2+1);
}
else return delString;
You have:
(delString.contains(subString))
This statement will always be true with the strings you've provided.
for(String s : delString.split(subString)) {
emp += s;
}
is this what you want?
String subString = "ONY";
String delString = "PONY";
String emp = "";
StringBuilder sb1=new StringBuilder(subString);
StringBuilder sb2=new StringBuilder(delString);
for(int i=0;i<sb2.length();i++)
{
for(int j=0;j<sb1.length();j++)
{
if(sb2.charAt(i)==sb1.charAt(j))
{
sb2.deleteCharAt(i);
}
}
}
emp=sb2.toString();
System.out.println(emp);
Sorry!!I have revamped the code but looks like its going to work fine...the problem with the string class is its immutability...The cod which you wrote doesnt give the require output...if it gives it can delete only first character i.e only O in your case Y is not getting deleted so i converted into StringBuffer class and wrote that..Happy Coding!

Find word in random string

Say I have a string that may look like:
"RAHDTWUOPO"
I know the word I'm looking for, for example:
"WORD"
what would be the best method for finding if I can make up "WORD" with a string like "RAHDTWUOPO"
EDIT:
Because of this question being unclear Id thought Id put more detail. What I wanted to achieve was to find if a word I knew beforehand could be made up from a random string of letters. Wasn't sure how to go about this, with a loop or if there was some other method.
I had come up with something quickly in my head but I knew it was to much effort, but I'll put it here to make this question more clearer of what I wanted to achieve.
public class MyLetterObject {
private String letter;
private Boolean used;
public String getText() {
return letter;
}
public void setLetter(String letter) {
this.letter = letter;
}
public Boolean getUsed() {
return used;
}
public void setUsed(Boolean used) {
this.used = used;
}
}
boolean ContainsWord(String Word, String RandomLetterString) {
List<MyLetterObject> MyLetterList = new ArrayList<MyLetterObject>();
for (char ch : RandomLetterString.toCharArray()) {
MyLetterObject mlo = new MyLetterObject();
mlo.setLetter(String.valueOf(ch));
mlo.setUsed(false);
MyLetterList.add(mlo);
}
String sMatch = "";
for (char Wordch : Word.toCharArray()) {
for (MyLetterObject o : MyLetterList) {
if (o.getUsed() == false
&& String.valueOf(Wordch).equals(o.getText())) {
o.setUsed(true);
sMatch = sMatch + String.valueOf(Wordch);
break;
}
}
}
if (sMatch.equals(Word)) {
return true;
} else {
return false;
}
}
As you can see to much effort. Evgeniy Dorofeev answer is much more better for the purpose of just finding if a word can be made from a string made up of letters in a random order.
try
boolean containsWord(String s, String w) {
List<Character> list = new LinkedList<Character>();
for (char c : s.toCharArray()) {
list.add(c);
}
for (Character c : w.toCharArray()) {
if (!list.remove(c)) {
return false;
}
}
return true;
}
You search every letter, one by one in the first String.
String randomString = "RAHDTWUOPO";
String word = "WORD";
for(int i=0;i<word.length; i++){
if(randomString.contains(word.charAt(i))){
// Yey, another letter found
}
}
Then you only have to test if for every i the letter was actually found, if not, the word is not included in the randomString.
You need find, that all letters from your word "WORD" exists in input string at list once.
Simple loop will do it for you but performance will not be best one.
You can use guava library multiset:
http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained
Multiset wordsMultiset = HashMultiset.create();wordsMultiset.addAll(words);// now we can use wordsMultiset.count(String) to find the count of a word
This example is about words, adopte it to chars of your input string.

Categories