How to strip ' \n' in Java? - java

I have the following piece of code:
String name='ishtiaq\n'
How can I strip the newline-character?
Thank you in advance.

If the "\n" always occurs at the end, use String.trim() [this won't remove the period, however, if you care about doing that]. If you want to eliminate internal newlines, you could use String.replaceAll(). You could also copy the string into a StringBuilder or array to construct a new string, skipping over the elements you wish to discard, or you could locate the relevant indices and use substring() to get a substring that excludes the elements you don't like. In short, there are many ways to do this.
Here is just one of many ways to do it (this one removing both the period symbol and the newline):
private static String nameWithoutSuffix(String nameWithSuffix) {
int periodIndex = nameWithSuffix.indexOf('.');
int newlineIndex = nameWithSuffix.indexOf('\n');
if ((periodIndex == -1) && (newlineIndex == -1)) {
return nameWithSuffix;
}
int suffixStartIndex = -1;
if (periodIndex != -1) {
suffixStartIndex = periodIndex;
}
if ((newlineIndex != -1)
&& ((suffixStartIndex == -1)
|| (newlineIndex < suffixStartIndex))) {
suffixStartIndex = newlineIndex;
}
return nameWithSuffix.substring(0, suffixStartIndex);
}

Java Strings have .replace!
With it, your problem becomes super easy:
String strippedString = name.replace("\n", "");
Remember: When you use replace, Java won't work on the existing String. That's why you'll have to store the return-value in another object. (You could use the same of course.)

Related

How to compare two strings, of different length to find identical substring

The problem is:
Client accounts are filed under a classification system using codes eg MA400. I need a method that will reset the original MA400 to an updated code such as MA400.4. If the new code has 5 characters to which the original is reset then the method returns true. Not the best wording but that is all I have right now.
It hasn't been specified if the characters need to be in the same order, eg.
String str = "abc123";
String newStr = "xyz123abc";
I am assuming they need to be in the same order. So the above strings would only have 3 like characters.
char[]array = str.toCharArray();
char[]array2 = newStr.toCharArray();
I am thinking now to use a compareTo method on the two arrays, but I am not sure how this would work exactly. Perhaps I could use a for loop to stop comparing after the final element in the shortest string but not entirely sure if I can do much with that.
I feel like I am going about this in the wrong way and there is a less complicated way to check for like characters in a string?
From what I understand something like this will work. Remember this will only count unique characters. Order does not matter
public static boolean matchingChar(final String st1, final String st2) {
if(st1 == null || st2 == null || st1.length() < 5 || st2.length() < 5) {
return false;
}
//This is if you wish unique characters to be counted only
//Otherwise you can use simple int count = 0
HashSet<Character> found = new HashSet<Character>();
//found.size() < 5 so the loop break as soon as the condition is met
for(int i = 0; i < st1.length() && found.size() < 5; i++) {
if(st2.indexOf(st1.charAt(i)) != -1) {
found.add(st1.charAt(i));
}
}
return found.size() >= 5;
}

Faster way to split a string in java then add to an ArrayList

For a school project I was asked to write a simple math parser in Java. The program works fine. So fine that I used NetBeans profiler tool to check the performance of the program. For that I made a loop of 1000 calls to the math parser of the following expression: "1-((x+1)+1)*2", where x was replaced by the current loop count. It took 262ms. The thing is, it took 50% of the time in the method splitFormula, which I shall present below:
private static void splitFormula(String formula){
partialFormula=new ArrayList<>();
for(String temp: formula.split("\\+|\\-|\\*|\\/"))
partialFormula.add(temp);
}
, where partialFormula is an ArrayList of Strings. To numerically evaluate an expression I need to call the splitFormula method various times so I really need to clear the contents of the partialFormula ArrayList - first line.
My question is: is there a faster way to split a string then add the partial strings to the an arraylist? Or is there some other method that can be used to split a string then use the substrings?
Regular expressions can slow things down (String#split uses regex). In general, if you want to write easy code, regex is good, but if you want fast code, see if there is another way. Try doing this without regex:
Edit: This should be a better method (keep track of the indices instead of append to a StringBuilder):
private static void splitFormula(String formula){
partialFormula.clear(); // since there is a method for this, why not use it?
int lastIndex = 0;
for (int index = 0; index < formula.length(); index++) {
char c = formula.charAt(index);
if (c == '-' || c == '+' || c == '*' || c == '/') {
partialFormula.add(formula.substring(lastIndex, index));
lastIndex = index + 1; //because if it were index, it would include the operator
}
}
partialFormula.add(formula.substring(lastIndex));
}
StringBuilder approach:
private static void splitFormula(String formula){
partialFormula.clear();
StringBuilder newStr = new StringBuilder();
for (int index = 0; index < formula.length(); index++) {
char c = formula.charAt(index);
if (c == '-' || c == '+' || c == '*' || c == '/') {
partialFormula.add(newStr.toString());
newStr.setLength(0);
} else {
newStr.append(c);
}
}
partialFormula.add(newStr.toString());
}
If we look at the source code for String#split, it becomes apparent why that is slower (from GrepCode):
public String[] split(String regex, int limit) {
return Pattern.compile(regex).split(this, limit);
}
It compiles a regex every time! Thus, we can see that another way of speeding up the code is to compile our regex first, then use the Pattern#split to split:
//In constructor, or as a static variable.
//This regex is a better form of yours.
Pattern operatorPattern = Pattern.compile("[-*+/]");
...
private static void splitFormula(String formula){
partialFormula.clear();
for(String temp: operatorPattern.split(formula)) {
partialFormula.add(temp);
}
}
You don't need a for loop. split returns an array, and you can create an ArrayList out of the array:
partialFormula = new ArrayList<>(Arrays.asList(formula.split("\\+|\\-|\\*|\\/")));
Whether this is significantly faster or not, I don't know.
Try pre-allocating the ArrayList beforehand so we do not have to pay for reallocation when the list grows. The number 20 below is just a placeholder. Pick a number that is a little bigger than the largest expression you expect.
partialFormula=new ArrayList<String>(20);
See this question for a discussion of what this might gain you.
This will create an arrayList of strings.
String a= "1234+af/d53";
char [] blah=a.toCharArray();
ArrayList<String> list=new ArrayList<String>();
for (int i = 0; i < blah.length; i++) {
list.add(Character.toString(blah[i]));
}

String not populating properly

I am writing a program that is going to read a string from a file, and then remove anything that isn't 1-9 or A-Z or a-z. The A-Z values need to become lowercase. Everything seems to run fine, I have no errors, however my output is messed up. It seems to skip certain characters for no reason whatsoever. I've looked at it and tweaked it but nothing works. Can't figure out why it is randomly skipping certain characters because I believe my if statements are correct. Here is the code:
String dataIn;
int temp;
String newstring= "";
BufferedReader file = new BufferedReader(new FileReader("palDataIn.txt"));
while((dataIn=file.readLine())!=null)
{
newstring="";
for(int i=0;i<dataIn.length();i++)
{
temp=(int)dataIn.charAt(i);
if(temp>46&&temp<58)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>96&&temp<123)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>64&&temp<91)
{
newstring=newstring+Character.toLowerCase(dataIn.charAt(i));
}
i++;
}
System.out.println(newstring);
}
So to give you an example, the first string I read in is :
A sample line this is.
The output after my program runs through it is this:
asmlietis
So it is reading the A making it lowercase, skips the space like it is suppose to, reads the s in, but then for some reason skips the "a" and the "m" and goes to the "p".
You're incrementing i in the each of the blocks as well as in the main loop "header". Indeed, because you've got one i++; in an else statement for the last if statement, you're sometimes incrementing i twice during the loop.
Just get rid of all the i++; statements other than the one in the for statement declaration. For example:
newstring="";
for(int i=0;i<dataIn.length();i++)
{
temp=(int)dataIn.charAt(i);
if(temp>46&&temp<58)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>96&&temp<123)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>64&&temp<91)
{
newstring=newstring+Character.toLowerCase(dataIn.charAt(i));
}
}
I wouldn't stop editing there though. I'd also:
Use a char instead of an int as the local variable for the current character you're looking at
Use character literals for comparisons, to make it much clearer what's going on
Use a StringBuilder to build up the string
Declare the variable for the output string for the current line within the loop
Use if / else if to make it clear you're only expecting to go into one branch
Combine the two paths that both append the character as-is
Fix the condition for numbers (it's incorrect at the moment)
Use more whitespace for clarity
Specify a locale in toLower to avoid "the Turkey problem" with I
So:
String line;
while((line = file.readLine()) != null)
{
StringBuilder builder = new StringBuilder(line.length());
for (int i = 0; i < line.length(); i++) {
char current = line.charAt(i);
// Are you sure you want to trim 0?
if ((current >= '1' && current <= '9') ||
(current >= 'a' && current <= 'z')) {
builder.append(current);
} else if (current >= 'A' && current <= 'Z') {
builder.append(Character.toLowerCase(current, Locale.US));
}
}
System.out.println(builder);
}

Multiple arguments for !somearray.contains

Is it possible to have multiple arguments for a .contains? I am searching an array to ensure that each string contains one of several characters. I've hunted all over the web, but found nothing useful.
for(String s : fileContents) {
if(!s.contains(syntax1) && !s.contains(syntax2)) {
found.add(s);
}
}
for (String s : found) {
System.out.println(s); // print array to cmd
JOptionPane.showMessageDialog(null, "Note: Syntax errors found.");
}
How can I do this with multiple arguments? I've also tried a bunch of ||s on their own, but that doesn't seem to work either.
No, it can't have multiple arguments, but the || should work.
!s.contains(syntax1+"") || !s.contains(syntax2+"") means s doesn't contain syntax1 or it doesn't contain syntax2.
This is just a guess but you might want s contains either of the two:
s.contains(syntax1+"") || s.contains(syntax2+"")
or maybe s contains both:
s.contains(syntax1+"") && s.contains(syntax2+"")
or maybe s contains neither of the two:
!s.contains(syntax1+"") && !s.contains(syntax2+"")
If syntax1 and syntax2 are already strings, you don't need the +""'s.
I believe s.contains("") should always return true, so you can remove it.
It seems that what you described can be done with a regular expression.
In regular expression, the operator | marks you need to match one of several choices.
For example, the regex (a|b) means a or b.
The regex ".*(a|b).*" means a string that contains a or b, and other then that - all is OK (it assumes one line string, but that can be dealt with easily as well if needed).
Code example:
String s = "abc";
System.out.println(s.matches(".*(a|d).*"));
s = "abcd";
System.out.println(s.matches(".*(a|d).*"));
s = "fgh";
System.out.println(s.matches(".*(a|d).*"));
Regular Exprsssions is a powerful tool that I recommend learning. Have a look at this tutorial, you might find it helpful.
There is not such thing as multiple contains.
if you require to validate that a list of string is included in some other string you must iterate through them all and check.
public static boolean containsAll(String input, String... items) {
if(input == null) throw new IllegalArgumentException("Input must not be null"); // We validate the input
if(input.length() == 0) {
return items.length == 0; // if empty contains nothing then true, else false
}
boolean result = true;
for(String item : items) {
result = result && input.contains(item);
}
return result;
}

Why is new line getting appended to my array element when I am trying to print this?

private int Index(String[] match,String keyword){
int m=0;
keyword=keyword+"1";
match[m]=match[m]+"1";
System.out.println("match:"+match[m]);
System.out.println("keyword:"+keyword);
System.out.println(match[m].equals(keyword));
while(!(match[m].equals("")) && !(match[m].equals(null))){
System.out.println("yes");
if(match[m].equals(keyword)){
break;
}
else
m++;
}
return m;
}
And I am getting following output (value of keyword is sparktg):
match:sparktg
1
keyword:sparktg1
false
Why in the case of match[m], there is a new line between "sparktg" & "1"?
If you have no control over the input, you can do a trim() before you use the inputs. This eliminates any \n and spaces.
if(match[m] != null) {
System.out.println("match:"+match[m].trim());
}
if(keyword != null) {
System.out.println("keyword:"+keyword.trim());
}
You can make it cleaner by writing a utility method to do this.
public String sanitize(String input) {
return input != null ? input.trim() : null;
}
and use it as so:
match[m] = sanitize(match[m]);
keyword = sanitize(keyword);
The only reason I can see is that match[0] already ends in a newline. You should check by outputting match[0] before adding the "1". A good practice is to output in this form:
System.out.println("|"+match[0]+"|");
...thus using the | to clearly mark where your string starts and ends.
You can use trim() to cut off any whitespace, including newlines:
match[m] = match[m].trim() + "1";
However, this will also remove spaces and tabs, which may or may not be a problem for you. When I compare strings, I often trim both strings first, just to be safe, but only if you are disregarding whitespace.
Try this. Replace all the new line before parsing.
private static int Index(String[] match,String keyword){
int m=0;
for(int k=0;k<match.length;k++){
if(match[k]!=null)
match[k]= match[k].replace("\n", "");
}
if(keyword!=null)
keyword= keyword.replace("\n", "");
keyword=keyword+"1";
match[m]=match[m]+"1";
System.out.println("match:"+match[m]);
System.out.println("keyword:"+keyword);
System.out.println(match[m].equals(keyword));
while(!(match[m].equals("")) && !(match[m].equals(null))){
System.out.println("yes");
if(match[m].equals(keyword)){
break;
}
else
m++;
}
return m;
}
That is not the answer, but notation about the code
match[m].equals(null) will throw an NullPointerException. The right way to check if match[m] not equals null is: mathc[m] != null before calling any method of your object. So use this:
match[m] != null && !match[m].equals("")
instead of this:
!match[m].equals("") && !match[m].equals(null)

Categories

Resources