I am trying to create a new directory using Java but I realized that the mkdir() don't work with strings that are made up of concat() method or using the '+' operand.
For example:
String keyword = "golden+retriever";
String folderName = removeChar(keyword);
String strDirectory = "C:/Users/Administrator/Desktop/"+folderName;
File newFolder = new File(strDirectory);
newFolder.mkdir();
The above code does not create the folder but it will work correctly if I were to use the directory without the '+' operand like this:
String strDirectory = "C:/Users/Administrator/Desktop/goldenretriever";
File newFolder = new File(strDirectory);
newFolder.mkdir();
Why is it so? Is there any ways to successfully create a directory using the '+' operand or the concat() method?
Update:
The '+' in the String is not a typo. The removeChar() method simply removes the '+' in order to create a folder without special characters.
Below is the code for removeChar():
public static String removeChar(String s)
{
StringBuffer buff = new StringBuffer(s.length());
buff.setLength(s.length());
int current = 0;
for (int i=0; i<s.length(); i++)
{
char cur = s.charAt(i);
if(cur != '+')
{
buff.setCharAt(current++, cur);
}
}
return buff.toString();
}
Please make sure that your path is proper otherwise windows allowed + as name of folder.
see for example if I have URL like : C:/TestWS/Test/TestingDir/ then your keyword
String keyword = "golden+retriever";
Java doesn't create all directories automatically so please make sure that this path already exist before creating final keyword dir : C:/TestWS/Test/TestingDir/
If TestingDir is not exist and trying to create "golden+retriever"; then java will not be going to create any directory.
What's wrong with your code is that the removeChar returns excess whitespace after the keyword. What you can do is trim it first before creating the file.
Try:
File newFolder = new File(strDirectory.trim());
And also I recommend you check if the folder exists first before creating it
if(!newFolder.exists()) {
newFolder.mkdir();
}
Although the original poster has gone with another more efficient solution to solve the problem, I'd like to point out why their original code was failing.
They created a new StringBuffer and made a copy of s at the top. They set the initial length to be equal to the length of the original string s. If they removed any number of pluses the new string is actually smaller than the original. In order to make sure the StringBuffer is of the correct length with no unused trailing characters you would have to set the length accordingly when finished.
To fix the original code would require changing:
return buff.toString();
To:
buff.setLength(current);
return buff.toString();
One could have reworked the code so the new StringBuffer buff started out blank and new characters are simply appended as needed. That could have been done with something like:
public static String removeChar(String s)
{
StringBuffer buff = new StringBuffer();
for (int i=0; i<s.length(); i++)
{
char cur = s.charAt(i);
if(cur != '+')
buff.append(cur);
}
return buff.toString();
}
Related
I'm currently trying to loop through a String and identity a specific character within that string then add a specific character following on from the originally identified character.
For example using the string: aaaabbbcbbcbb
And the character I want to identify being: c
So every time a c is detected a following c will be added to the string and the loop will continue.
Thus aaaabbbcbbcbb will become aaaabbbccbbccbb.
I've been trying to make use of indexOf(),substring and charAt() but I'm currently either overriding other characters with a c or only detecting one c.
I know you've asked for a loop, but won't something as simple as a replace suffice?
String inputString = "aaaabbbcbbcbb";
String charToDouble = "c";
String result = inputString.replace(charToDouble, charToDouble+charToDouble);
// or `charToDouble+charToDouble` could be `charToDouble.repeat(2)` in JDK 11+
Try it online.
If you insist on using a loop however:
String inputString = "aaaabbbcbbcbb";
char charToDouble = 'c';
String result = "";
for(char c : inputString.toCharArray()){
result += c;
if(c == charToDouble){
result += c;
}
}
Try it online.
Iterate over all the characters. Add each one to a StringBuilder. If it matches the character you're looking for then add it again.
final String test = "aaaabbbcbbcbb";
final char searchChar = 'c';
final StringBuilder builder = new StringBuilder();
for (final char c : test.toCharArray())
{
builder.append(c);
if (c == searchChar)
{
builder.append(c);
}
}
System.out.println(builder.toString());
Output
aaaabbbccbbccbb
You probably are trying to modify a String in java. Strings in Java are immutable and cannot be changed like one might do in c++.
You can use StringBuilder to insert characters. eg:
StringBuilder builder = new StringBuilder("acb");
builder.insert(1, 'c');
The previous answer suggesting String.replace is the best solution, but if you need to do it some other way (e.g. for an exercise), then here's a 'modern' solution:
public static void main(String[] args) {
final String inputString = "aaaabbbcbbcbb";
final int charToDouble = 'c'; // A Unicode codepoint
final String result = inputString.codePoints()
.flatMap(c -> c == charToDouble ? IntStream.of(c, c) : IntStream.of(c))
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
assert result.equals("aaaabbbccbbccbb");
}
This looks at each character in turn (in an IntStream). It doubles the character if it matches the target. It then accumulates each character in a StringBuilder.
A micro-optimization can be made to pre-allocate the StringBuilder's capacity. We know the maximum possible size of the new string is double the old string, so StringBuilder::new can be replaced by () -> new StringBuilder(inputString.length()*2). However, I'm not sure if it's worth the sacrifice in readability.
I have a String array containing a poem which has deliberate spelling mistakes. I am trying to iterate through the String array to identify the spelling mistakes by comparing the String array to a String array containing a dictionary. If possible I would like a suggestion that allows me to continue using nested for loops
for (int i = 0; i < poem2.length; i++) {
boolean found = false;
for (int j = 0; j < dictionary3.length; j++) {
if (poem2[i].equals(dictionary3[j])) {
found = true;
break;
}
}
if (found==false) {
System.out.println(poem2[i]);
}
}
The output is printing out the correctly spelt words as well as the incorrectly spelt ones and I am aiming to only print out the incorrectly spelt ones. Here is how I populate the 'dictionary3' and 'poem2' arrays:
char[] buffer = null;
try {
BufferedReader br1 = new BufferedReader(new
java.io.FileReader(poem));
int bufferLength = (int) (new File(poem).length());
buffer = new char[bufferLength];
br1.read(buffer, 0, bufferLength);
br1.close();
} catch (IOException e) {
System.out.println(e.toString());
}
String text = new String(buffer);
String[] poem2 = text.split("\\s+");
char[] buffer2 = null;
try {
BufferedReader br2 = new BufferedReader(new java.io.FileReader(dictionary));
int bufferLength = (int) (new File(dictionary).length());
buffer2 = new char[bufferLength];
br2.read(buffer2, 0, bufferLength);
br2.close();
} catch (IOException e) {
System.out.println(e.toString());
}
String dictionary2 = new String(buffer);
String[] dictionary3 = dictionary2.split("\n");
Your basic problem is in line
String dictionary2 = new String(buffer);
where you ware trying to convert characters representing dictionary stored in buffer2 but you used buffer (without 2 suffix). Such style of naming your variables may suggest that you either need a loop, or in this case separate method which will return for selected file array of words it holds (you can also add as method parameter delimiter on which string should be split).
So your dictionary2 held characters from buffer which represented poem, not dictionary data.
Another problem is
String[] dictionary3 = dictionary2.split("\n");
because you are splitting here only on \n but some OS like Windows use \r\n as line separator sequence. So your dictionary array may contain words like foo\r instead of foo which will cause poem2[i].equals(dictionary3[j] to always fail.
To avoid this problem you can split on \\R (available since Java 8) or \r?\n|\r.
There are other problems in your code like closing resource within try section. If any exception will be thrown before, close() will never be invoked leaving unclosed resources. To solve it close resources in finally section (which is always executed after try - regardless if exception will be thrown or not), or better use try-with-resources.
BTW you can simplify/clarify your code responsible for reading words from files
List<String> poem2 = new ArrayList<>();
Scanner scanner = new Scanner(new File(yourFileLocation));
while(scanner.hasNext()){//has more words
poem2.add(scanner.next());
}
For dictionary instead of List you should use Set/HashSet to avoid duplicates (usually sets also have better performance when checking if they contain some elements or not). Such collections already provide methods like contains(element) so you wouldn't need that inner loop.
I copied your code and ran it, and I noticed two issues. Good news is, both are very quick fixes.
#1
When I printed out everything in dictionary3 after it is read in, it is the exact same as everything in poem2. This line in your code for reading in the dictionary is the problem:
String dictionary2 = new String(buffer);
You're using buffer, which was the variable you used to read in the poem. Therefore, buffer contains the poem and your poem and dictionary end up the same. I think you want to use buffer2 instead, which is what you used to read in the dictionary:
String dictionary2 = new String(buffer2);
When I changed that, the dictionary and poem appear to have the proper entries.
#2
The other problem, as Pshemo pointed out in their answer (which is completely correct, and a very good answer!) is that you are splitting on \n for the dictionary. The only thing I would say differently from Pshemo here is that you should probably split on \\s+ just like you did for the poem, to stay consistent. In fact, when I debugged, I noticed that the dictionary words all have "\r" appended to the end, probably because you were splitting on \n. To fix this, change this line:
String[] dictionary3 = dictionary2.split("\n");
To this:
String[] dictionary3 = dictionary2.split("\\s+");
Try changing those two lines, and let us know if that resolves your issue. Best of luck!
Convert your dictionary to an ArrayList and use Contains instead.
Something like this should work:
if(dictionary3.contains(poem2[i])
found = true;
else
found = false;
With this method you can also get rid of that nested loop, as the contains method handles that for you.
You can convert your Dictionary to an ArrayList with the following method:
new ArrayList<>(Arrays.asList(array))
Hopefully this will be an easy answer and i'm just overlooking something minor.
Goal: take an array list (which currently contains lines of text from a text file) and set a String variable equal a specified array list position.
At the moment, each line is raw text taken from an Encyclopedia file. I need to be able to remove non alpha's via the .replaceAll function. However, my current program returns a null pointer exception and I'm having some trouble understanding why. I'm fairly new to Java so full answers and explanations are much appreciated.
my code: (My teacher told us to use EasyReader class to make our lives, well easier...)
EasyReader fileIn = new EasyReader("Encyclopedia.txt");
public void createList()
{
String x=fileIn.readLine();
ArrayList<String> list = new ArrayList<String>();
while((!fileIn.eof()))
{
String y=fileIn.readLine();
list.add(y);
}
int count=0;
while(count<list.size())
{
String temp=list.get(count);
temp.replaceAll("[^a-zA-z ]", ""); //null pointer points to this line
temp.toLowerCase(); //and this line
list.set(count, temp);
count++;
}
count=0;
while(count<list.size());
{
System.out.println(list.get(count));
count++;
}
System.out.println(list.size());
while(count<list.size())
{
fileOut.println(list.get(count));
count++;
}
fileOut.close();
}
thanks in advance for the help :)
I think I found your error!
Your while loop should go only to list.size() - 1 not the list.size() you have there. See below:
while(count<list.size()- 1)
{
String temp=list.get(count);
temp.replaceAll("[^a-zA-z ]", ""); //null pointer points to this line
temp.toLowerCase(); //and this line
list.set(count, temp);
count++;
}
Try replacing the two lines that you commented with this instead:
temp = temp.replaceAll("[^a-zA-z ]", "");
temp = temp.toLowerCase();
This is because the replaceAll() method does not change the original string itself, but rather returns a new string with the characters replaced. Same thing with toLowerCase().
You made two mistakes:
1) the replaceAll regex should be temp.replaceAll("[^a-zA-z]", "") (no space after z)
2) you can combine two lines into one method temp.replaceAll("[^a-zA-z]", "").toLowerCase()
3) you need to save your newly returned String to the original variable temp:
temp = temp.replaceAll("[^a-zA-z]", "").toLowerCase();
as #Suitangi mentioned, replaceAll() method does not change the original string itself, but rather returns a new string with the characters replaced. Same thing with toLowerCase().
Hope that helps.
EDIT:
In the last iteration String temp = null;
Add if condition to check it, before regex:
if (temp!=null){
temp = temp.replaceAll("[^a-zA-z]", "").toLowerCase();
list.set(count, temp);
count++;
}
I am new to Java programming and I was writing code to replace spaces in Strings with %20 and return the final String. Here is the code for the problem. Since I am new to programming please tell me what I did wrong. Sorry for my bad English.
package Chapter1;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Problem4 {
public char[] replaceSpaces(char[] str_array, int length)
{
int noOfSpaces=0,i,newLength;
for(i=0;i<length;i++)
{
if(str_array[i]==' ')
{
noOfSpaces++;
}
newLength = length + noOfSpaces * 2;
str_array[newLength]='\0';
for(i=0;i<length-1;i++)
{
if(str_array[i]==' ')
{
str_array[newLength-1]='0';
str_array[newLength-2]='2';
str_array[newLength-3]='%';
newLength = newLength-3;
}
str_array[newLength-1]=str_array[i];
newLength = newLength - 1;
}
}
return str_array;
}
public static void main(String args[])throws Exception
{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please enter the string:");
String str = reader.readLine();
char[] str_array = str.toCharArray();
int length = str.length();
Problem4 obj = new Problem4();
char[] result = obj.replaceSpaces(str_array, length);
System.out.println(result);
}
}
But I get the following error:
Please enter the string:
hello world
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11
at Chapter1.Problem4.replaceSpaces(Problem4.java:19)
at Chapter1.Problem4.main(Problem4.java:46)
How about using String.replaceAll():
String str = reader.readLine();
str = str.replaceAll(" ", "02%");
Sample code here
EDIT:
The problem is at line 19:
str_array[newLength]='\0';//<-- newLength exceeds the char array size
Here array is static i.e. the size is fixed you can use StringBuilder, StringBuffer, etc to build the new String without worrying about the size for such small operations.
Assuming that you want to see what mistakes you made when implementing your approach, instead of looking for a totally different approach:
(1) As has been pointed out, once an array has been allocated, its size cannot be changed. Your method takes str_array as a parameter, but the resulting array will likely be larger than str_array. Therefore, since str_array's length cannot be changed, you'll need to allocate a new array to hold the result, rather than using str_array. You've computed newLength correctly; allocate a new array of that size:
char[] resultArray = new char[newLength];
(2) As Elliott pointed out, Java strings don't need \0 terminators. If, for some reason, you really want to create an array that has a \0 character at the end, then you have to add 1 to your computed newLength to account for the extra character.
(3) You're actually creating the resulting array backward. I don't know if that is intentional.
if(str_array[i]==' ')
{
str_array[newLength-1]='0';
str_array[newLength-2]='2';
str_array[newLength-3]='%';
newLength = newLength-3;
}
str_array[newLength-1]=str_array[i];
newLength = newLength - 1;
i starts with the first character of the string and goes upward; you're filling in characters starting with the last character of the string (newLength) and going backward. If that's what you intended to do, it wasn't clear from your question. Did you want the output to be "dlrow%20olleh"?
(4) If you did intend to go backward, then what the above code does with a space is to put %20 in the string (backwards), but then it also puts the space into the result. If the input character is a space, you want to make sure you don't execute the two lines that copy the input character to the result. So you'll need to add an else. (Note that this problem will lead to an out-of-bounds error, because you're trying to put more characters into the result than you computed.) You'll need to have an else in there even if you really meant to build the string forwards and need to change the logic to make it go forward.
Java arrays are not dynamic (they are Object instances, and they have a field length property that does not change). Because they store the length as a field, it is important to know that they're not '\0' terminated (your attempt to add such a terminator is causing your index out of bounds Exception). Your method doesn't appear to access any instance fields or methods, so I'd make it static. Then you could use a StringBuilder and a for-each loop. Something like
public static char[] replaceSpaces(char[] str_array) {
StringBuilder sb = new StringBuilder();
for (char ch : str_array) {
sb.append((ch != ' ') ? ch : "%20");
}
return sb.toString().toCharArray();
}
Then call it like
char[] result = replaceSpaces(str_array);
Finally, you might use String str = reader.readLine().replace(" ", "+"); or replaceAll(" ", "%20") as suggested by #Arvind here.
P.S. When you finally get your result you'll need to fix your call to print it.
System.out.println(Arrays.toString(result));
or
System.out.println(new String(result));
A char[] is not a String and Java arrays (disappointingly) don't override toString() so you'll get the one from Object.
please tell me what I did wrong
You tried to replace a single character with three characters %20. That's not possible because arrays are fixed length.
Therefore you must allocate a new char[] and copy the characters from str_array into the new array.
for (i = 0; i < length; i++) {
if (str_array[i] == ' ') {
noOfSpaces++;
}
}
newLength = length + noOfSpaces * 2;
char[] newArray = new char[newLength];
// copy characters from str_array into newArray
The exception is raised in this line str_array[newLength]='\0'; because value of newLength is greater than length of str_array.
Array size cannot be increased once it is defined. So try the alternative solution.
char[] str_array1=Arrays.copyOf(str_array, str_array.length+1);
str_array1[newLength]='\0';
don't forget to import the new package import java.util.Arrays;
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)