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.
Related
I created a JAVA code, and I don't have any errors, but when I run the code, the output does this:
Enter a word: Thank you for entering a word! And it does not let me enter anything, when I intend for the code to let me enter a word, then it checks if it is a word, and gives the answer if it is a word, or none if it isn't. (It is my first time asking on this site) Here's the code:
package files;
import java.util.Scanner;
public class Testprinter {
static boolean myBoolean = false;
static Scanner userInput = new Scanner(System.in);
public static void main(String[] args){
String usersInput;
while(myBoolean != true)
{
System.out.print("Enter a word: ");
usersInput = userInput.toString();
myBoolean = checkInput(usersInput);
}
checkifComplete();
}
public static boolean checkInput(String usersInput){
if(usersInput == (String)usersInput)
{
return true;
} else { return false; }
}
public static void checkifComplete(){
if(myBoolean = true){
System.out.print("Thank you for entering a word!");
}
}
}
This line is wrong:
if (usersInput == (String)usersInput)
It should be:
if (usersInput.equals(usersInput))
In Java, strings (and in general: all objects, that is all types that are non-primitive) must me compared using the equals() method, which tests for equality. The == operator is fine for testing equality between primitive types, but for objects it tests for identity - a different concept, and 99% of the time, not what you want.
And besides, you're comparing a string with itself! it'll always return true, I'm quite sure that's not what you want to do… notice that the parameter must have a different name, currently it's called just like the attribute. Perhaps this is what you meant?
public static boolean checkInput(String input) {
return usersInput.equals(input);
}
You forgot scanner.nextLine(); thats reason its not asking you enter anything.
Instead of usersInput = userInput.toString();
Use:
String usersInputStr = scanner.nextLine();
Follow this link - for how to use scanner: How can I read input from the console using the Scanner class in Java?
Your issue is using userinput.toString(), when you should be using usersInput = userInput.next();. You are currently retrieving the string representation of the scanner, not getting a word.
Corrected main:
public static void main(String[] args){
String usersInput;
while(myBoolean != true)
{
System.out.print("Enter a word: ");
usersInput = userInput.next();
myBoolean = checkInput(usersInput);
}
checkifComplete();
}
Recentrly I found very helpful method in StringUtils library which is
StringUtils.stripAccents(String s)
I found it really helpful with removing any special characters and converting it to some ASCII "equivalent", for instace ç=c etc.
Now I am working for a German customer who really needs to do such a thing but only for non-German characters. Any umlauts should stay untouched. I realised that strinAccents won't be useful in that case.
Does anyone has some experience around that stuff?
Are there any useful tools/libraries/classes or maybe regular expressions?
I tried to write some class which is parsing and replacing such characters but it can be very difficult to build such map for all languages...
Any suggestions appriciated...
Best built a custom function. It can be like the following. If you want to avoid the conversion of a character, you can remove the relationship between the two strings (the constants).
private static final String UNICODE =
"ÀàÈèÌìÒòÙùÁáÉéÍíÓóÚúÝýÂâÊêÎîÔôÛûŶŷÃãÕõÑñÄäËëÏïÖöÜüŸÿÅåÇçŐőŰű";
private static final String PLAIN_ASCII =
"AaEeIiOoUuAaEeIiOoUuYyAaEeIiOoUuYyAaOoNnAaEeIiOoUuYyAaCcOoUu";
public static String toAsciiString(String str) {
if (str == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int index = 0; index < str.length(); index++) {
char c = str.charAt(index);
int pos = UNICODE.indexOf(c);
if (pos > -1)
sb.append(PLAIN_ASCII.charAt(pos));
else {
sb.append(c);
}
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(toAsciiString("Höchstalemannisch"));
}
My gut feeling tells me the easiest way to do this would be to just list allowed characters and strip accents from everything else. This would be something like
import java.util.regex.*;
import java.text.*;
public class Replacement {
public static void main(String args[]) {
String from = "aoeåöäìé";
String result = stripAccentsFromNonGermanCharacters(from);
System.out.println("Result: " + result);
}
private static String patternContainingAllValidGermanCharacters =
"a-zA-Z0-9äÄöÖéÉüÜß";
private static Pattern nonGermanCharactersPattern =
Pattern.compile("([^" + patternContainingAllValidGermanCharacters + "])");
public static String stripAccentsFromNonGermanCharacters(
String from) {
return stripAccentsFromCharactersMatching(
from, nonGermanCharactersPattern);
}
public static String stripAccentsFromCharactersMatching(
String target, Pattern myPattern) {
StringBuffer myStringBuffer = new StringBuffer();
Matcher myMatcher = myPattern.matcher(target);
while (myMatcher.find()) {
myMatcher.appendReplacement(myStringBuffer,
stripAccents(myMatcher.group(1)));
}
myMatcher.appendTail(myStringBuffer);
return myStringBuffer.toString();
}
// pretty much the same thing as StringUtils.stripAccents(String s)
// used here so I can demonstrate the code without StringUtils dependency
public static String stripAccents(String text) {
return Normalizer.normalize(text,
Normalizer.Form.NFD)
.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
}
}
(I realize the pattern doesn't probably contain all the characters needed, but add whatever is missing)
This might give you a work around. here you can detect the language and get the specific text only.
EDIT:
You can have the raw string as an input, put the language detection to German and then it will detect the German characters and will discard the remaining.
I'm trying to write some code that will tell me if the first letter of one string equals the first letter of another. I can't figure out how to compare a string to the return of charAt(). Help?
public class CharAtTest
{
public static void main(String [] args)
{
String name = "joe";
String initial = "j";
if(initial.equals(name.charAt(0)))
{
System.out.println("Sucess");
}else{
System.out.println("Fail");
}
}
}
You could use:
if (initial.charAt(0) == name.charAt(0))
or better
if (name.startsWith(initial)) {
charAt(), like the name implies, returns a char, not a string. So make initial a char instead.
Simply do this:
String name = "joe";
char initial = 'j';
if (name.charAt(0) == initial) {
// ...
}
Another way would be:
String.valueOf(name.charAt(0));
Or:
Character.toString(name.charAt(0));
But the implicit way (see ivanovic's answer) works as well
name.charAt(0) + ""
This is a problem from the CodingBat website. I am pasting the problem first and discussing my efforts after that:
Given two strings, base and remove, return a version of the base string where all instances of the remove string have been removed (not case sensitive). You may assume that the remove string is length 1 or more. Remove only non-overlapping instances, so with "xxx" removing "xx" leaves "x".
withoutString("Hello there", "llo") → "He there"
withoutString("Hello there", "e") → "Hllo thr"
withoutString("Hello there", "x") → "Hello there"
This is what I wrote so far:
public String withoutString(String base, String remove) {
int len_b=base.length();
int len_r = remove.length();
String result="";
if(len_b<1 || len_r<1)
return "";
for (int i =0;i<=len_b-len_r;i++)
{
if(base.substring(i,i+len_r).equals(remove))
{
i=i+len_r-1;
}
else
{
result=result+base.substring(i,i+1);
}
}
if(!(base.substring(len_b-len_r+1, len_b).equals(remove)))
result=result+base.substring(len_b-len_r+1, len_b);
return result;
}
This passes all the test cases except for the ones where the removal of the string should be case-insensitive.
For example: withoutString("This is a FISH", "IS") → "Th a FH"
My code gives me "This is a FH" as I haven't handled case sensitivity in my code. I know that with Regex this could be done in one line. I am more interested in knowing if there is a way to handle these kinds of test cases in my present code.
Also, please let me know if my code could be made more efficient/elegant.
String has an equalsIgnoreCase(String s) method.
you can change this statement base.substring(i,i+len_r).equals(remove) to base.substring(i,i+len_r).equalsIgnoreCase(remove) using equalsIgnoreCase method.
hope helpful.
public String withoutString(String base, String remove)
{
String str=base;
String str1=remove;
String str3=str;
int k=str1.length();
for(int i=0;i<(str.length()-k+1);i++)
{
if(str1.equalsIgnoreCase(str.substring(i, i+k)))
{
String str4=str.substring(i, i+k);
str3=str3.replaceFirst(str4,"" );
}
}
return str3;
}
I did it without any looping :) I suppose it is not the best answer, but it works though
public String withoutString(String base, String remove) {
String lastString = base.replace(remove, "");
remove = remove.toLowerCase();
String veryLastString = lastString.replace(remove, "");
remove = remove.toUpperCase();
String veryVeryLastString = veryLastString.replace(remove, "");
return veryVeryLastString;
}
public String withoutString(String base, String remove) {
String b=base.toLowerCase();
String r=remove.toLowerCase();
if(b.length()<r.length()) return base;
if(b.contains(r)) b=b.replaceAll(r,"");
String temp="";
int j=0;
for(int i=0;i<base.length();i++)
if(j<b.length()){
if(base.substring(i,i+1).equalsIgnoreCase(b.substring(j,j+1))){
temp+=base.substring(i,i+1);
j++;
}
}
return temp;
}
What is the most elegant way to convert a hyphen separated word (e.g. "do-some-stuff") to the lower camel-case variation (e.g. "doSomeStuff") in Java?
Use CaseFormat from Guava:
import static com.google.common.base.CaseFormat.*;
String result = LOWER_HYPHEN.to(LOWER_CAMEL, "do-some-stuff");
With Java 8 there is finally a one-liner:
Arrays.stream(name.split("\\-"))
.map(s -> Character.toUpperCase(s.charAt(0)) + s.substring(1).toLowerCase())
.collect(Collectors.joining());
Though it takes splitting over 3 actual lines to be legible ツ
(Note: "\\-" is for kebab-case as per question, for snake_case simply change to "_")
The following method should handle the task quite efficient in O(n). We just iterate over the characters of the xml method name, skip any '-' and capitalize chars if needed.
public static String toJavaMethodName(String xmlmethodName) {
StringBuilder nameBuilder = new StringBuilder(xmlmethodName.length());
boolean capitalizeNextChar = false;
for (char c:xmlMethodName.toCharArray()) {
if (c == '-') {
capitalizeNextChar = true;
continue;
}
if (capitalizeNextChar) {
nameBuilder.append(Character.toUpperCase(c));
} else {
nameBuilder.append(c);
}
capitalizeNextChar = false;
}
return nameBuilder.toString();
}
Why not try this:
split on "-"
uppercase each word, skipping the first
join
EDIT: On second thoughts... While trying to implement this, I found out there is no simple way to join a list of strings in Java. Unless you use StringUtil from apache. So you will need to create a StringBuilder anyway and thus the algorithm is going to get a little ugly :(
CODE: Here is a sample of the above mentioned aproach. Could someone with a Java compiler (sorry, don't have one handy) test this? And benchmark it with other versions found here?
public static String toJavaMethodNameWithSplits(String xmlMethodName)
{
String[] words = xmlMethodName.split("-"); // split on "-"
StringBuilder nameBuilder = new StringBuilder(xmlMethodName.length());
nameBuilder.append(words[0]);
for (int i = 1; i < words.length; i++) // skip first
{
nameBuilder.append(words[i].substring(0, 1).toUpperCase());
nameBuilder.append(words[i].substring(1));
}
return nameBuilder.toString(); // join
}
If you don't like to depend on a library you can use a combination of a regex and String.format. Use a regex to extract the starting characters after the -. Use these as input for String.format. A bit tricky, but works without a (explizit) loop ;).
public class Test {
public static void main(String[] args) {
System.out.println(convert("do-some-stuff"));
}
private static String convert(String input) {
return String.format(input.replaceAll("\\-(.)", "%S"), input.replaceAll("[^-]*-(.)[^-]*", "$1-").split("-"));
}
}
Here is a slight variation of Andreas' answer that does more than the OP asked for:
public static String toJavaMethodName(final String nonJavaMethodName){
final StringBuilder nameBuilder = new StringBuilder();
boolean capitalizeNextChar = false;
boolean first = true;
for(int i = 0; i < nonJavaMethodName.length(); i++){
final char c = nonJavaMethodName.charAt(i);
if(!Character.isLetterOrDigit(c)){
if(!first){
capitalizeNextChar = true;
}
} else{
nameBuilder.append(capitalizeNextChar
? Character.toUpperCase(c)
: Character.toLowerCase(c));
capitalizeNextChar = false;
first = false;
}
}
return nameBuilder.toString();
}
It handles a few special cases:
fUnnY-cASe is converted to funnyCase
--dash-before-and--after- is converted to dashBeforeAndAfter
some.other$funky:chars? is converted to someOtherFunkyChars
For those who has com.fasterxml.jackson library in the project and don't want to add guava you can use the jaskson namingStrategy method:
new PropertyNamingStrategy.SnakeCaseStrategy.translate(String);
get The Apache commons jar for StringUtils. Then you can use the capitalize method
import org.apache.commons.lang.StringUtils;
public class MyClass{
public String myMethod(String str) {
StringBuffer buff = new StringBuffer();
String[] tokens = str.split("-");
for (String i : tokens) {
buff.append(StringUtils.capitalize(i));
}
return buff.toString();
}
}
As I'm not a big fan of adding a library just for one method, I implemented my own solution (from camel case to snake case):
public String toSnakeCase(String name) {
StringBuilder buffer = new StringBuilder();
for(int i = 0; i < name.length(); i++) {
if(Character.isUpperCase(name.charAt(i))) {
if(i > 0) {
buffer.append('_');
}
buffer.append(Character.toLowerCase(name.charAt(i)));
} else {
buffer.append(name.charAt(i));
}
}
return buffer.toString();
}
Needs to be adapted depending of the in / out cases.
In case you use Spring Framework, you can use provided StringUtils.
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.stream.Collectors;
public class NormalizeUtils {
private static final String DELIMITER = "_";
private NormalizeUtils() {
throw new IllegalStateException("Do not init.");
}
/**
* Take name like SOME_SNAKE_ALL and convert it to someSnakeAll
*/
public static String fromSnakeToCamel(final String name) {
if (StringUtils.isEmpty(name)) {
return "";
}
final String allCapitalized = Arrays.stream(name.split(DELIMITER))
.filter(c -> !StringUtils.isEmpty(c))
.map(StringUtils::capitalize)
.collect(Collectors.joining());
return StringUtils.uncapitalize(allCapitalized);
}
}
Iterate through the string. When you find a hypen, remove it, and capitalise the next letter.