Creating new object sets all existing ones to null (Java) - java

I have this method which is supposed to cut a String when it finds a symbos of + or - (it is part of a derivative calculator, so the idea is to get a bunch of small strings separated by + or - and then derivate them one by one. That's why i have that search for opened and closed parenthesis)
The problem is: When calling res = new String(); it will create a new String, but it will also set all the existing String objects in the array to null, which means the return of the method will always be an array with everything set to null (unless it does not find a + or - in the function).
Is there a way around this?
public static String[] cutString(String func)
{
int number_strings_res = 0;
int number_parenthesis = 0;
String[] res = new String[1];
res[0] = new String(func);
for(int i = 0; i < func.length(); i++)
{
if(func.charAt(i) == '+' || func.charAt(i) == '-')
{
for(int j = 0; j < i; j++)
{
if(func.charAt(j) == '(')
number_parenthesis++;
if(func.charAt(j) == ')')
number_parenthesis--;
}
if(number_parenthesis == 0)
{
res[number_strings_res] = "";
for(int j = 0; j < i; j++)
{
res[number_strings_res] += func.charAt(j);
}
number_strings_res++;
res = new String[number_strings_res + 1];
res[number_strings_res] = new String(Character.toString(func.charAt(i)));
number_strings_res++;
res = new String[number_strings_res + 1];
res[number_strings_res] = new String();
}
}
}
return res;
}

res = new String[number_strings_res + 1] allocates a new array and stores it to res. So that's the source of the immediate problem. You should probably be using a List, like ArrayList, instead if you don't know how long the collection will be.

When calling res = new String() ...
You have no such call, and it would not compile anyway.
'res' is declared as variable referring to a String array. When you execute res = new String[...] you naturally replace the entire array of Strings.
But I can't really figure out what you intend? Are you trying to extend the array? You can't, directly.
If you must use an array, look into Arrays.copyFrom. But an ArrayList would be easier.

Related

how to merge two strings into one by using chartAt() and arrays technique

as mentioned in the title, I got an error in each line inside for loop which says (variable expected) and this is my code
String s = "ABC";
String t = "DEFGH";
String merge = "";
// merge should looks like "ADBECFGH"
int i = 0;
for (; i < s.length(); i=i+2) {
merge.charAt(i) = s.charAt(i/2);
merge.charAt(i+1) = t.charAt(i/2);
}
for (; i < t.length()+s.length() ; i++) {
merge.charAt(i) = t.charAt(i-s.length());
}
am trying to use same technique with arrays which I think its very effective.
If you like take one letter from first string and then from other try this:
for (int i = 0; i < s.length() || i < t.length(); i++) {
if (i < s.length()) {
merge += String.valueOf(s.charAt(i));
}
if (i < t.length()) {
merge += String.valueOf(t.charAt(i));
}
}
This is condition that let you iterate till longer String finish
i < s.length() || i < t.length()
Another one, since you are manipulating Strings inside a loop, it is better to use StringBuilder instead of String.
String s = "ABC";
String t = "DEFGH";
StringBuilder merge = new StringBuilder();
for (int i = 0; i < s.length() || i < t.length(); i++) {
if (i < s.length()) {
merge.append(s.charAt(i));
}
if (i < t.length()) {
merge.append(t.charAt(i));
}
}
System.out.println(merge.toString());
The method charAt(int index) returns the character at the specified index(IT IS A GETTER NOT A SETTER). You cannot use it as
merge.charAt(i) = s.charAt(i/2)
one of the easiest ways to perform such operation is to use string operation such as concatination as shown in the below example
s="abc";
t="def";
System.out.print(s.concat(t));
You could simply use the .concact() method without using the for loop:
so your code would look like:
merge = s.concat(t);
try this : concatenate two string without inbuilt method and without + operator.
public static void main(String[] args) {
String s = "ABC";
String s1 = "DEF";
String merge = "";
char[]ch = new char[120];
for(int i=0;i<s.length();i++) {
ch[i] = s.charAt(i);
}
for(int i = 0;i<s1.length();i++) {
ch[s.length()+i] = s1.charAt(i);
}
System.out.println(ch);
}
CharacterIterator a = new StringCharacterIterator("haaaaallo");
CharacterIterator b = new StringCharacterIterator("12345");
StringBuilder output = new StringBuilder();
if(a.getEndIndex() < b.getEndIndex()) { //true -> swap a and b
CharacterIterator holder = a;
a = b;
b = holder;
}
while (a.current() != CharacterIterator.DONE) {
output.append(a.current());
while (b.current() != CharacterIterator.DONE) {
output.append(b.current());
break;
}
a.next();
b.next();
}
System.out.println(output.toString()); //h1a2a3a4a5allo
To show "the manual way". The used Strings can be any size.
I would go with #Bartek's answer its simple and easy to remember..
the complicated way to achieve this would be
String a = "abcdefgh";
String b = "ijklmnopqrst";
int i = 0;
StringBuilder merge = new StringBuilder();
for (; i < a.length() && i < b.length(); i++) {
merge.append(a.charAt(i)).append(b.charAt(i));
}
if (i < a.length())
merge.append(a.substring(i));
if (i < b.length())
merge.append(b.substring(i));
Only to avoid having if conditions inside the for loop.. (optimal only in case of large strings, strings of vastly different lengths)

Cannot update an array in Main from nested loops inside of Main. How can I assign it's value?

So, I am writing my program when suddenly, I run into a problem in which my three arrays print as null, 0 and null.
The program reads values from a file, and assigns them to the three arrays based on the iteration number.
Here is my code:
String mushroom []= new String [10];
int weight [] = new int [10];
String cooking[] = new String [10];
FileReader fr = new FileReader ("7J_Mushrooms.csv");
BufferedReader br = new BufferedReader (fr);
System.out.println("Mushroom\t\tWeight\t\tCooking\n=======================================================");
String line = "";
while ((line = br.readLine()) != null){
String [] temp = line.split(",");
for (int i = 0; i < temp.length; i++){
if(i == 0){
mushroom[i] = temp[i];
}
else if (i == 1){
weight[i] = Integer.parseInt(temp[i]);
}
else{
cooking[i] = temp[i];
}
}
}
// This bit just sorts them by weight in ascending order like a parallel array
for (int i = 0; i < weight.length-1; i++){
for (int j = 0; j < weight.length-1;j++){
if (weight[j] > weight[j+1]){
int temp = weight [j];
String tempMush = mushroom [j];
String tempCook = cooking [j];
weight[j] = weight[j+1];
mushroom[j] = mushroom[j+1];
cooking[j] = cooking[j+1];
weight[j+1] = temp;
mushroom[j+1] = tempMush;
cooking[j+1] = tempCook;
}
}
}
for (int i = 0; i < weight.length; i++){
System.out.print(mushroom[i] + "\t\t" + weight[i] + "\t\t" + cooking[i] + "\n");
}
When I print the values of the arrays inside of the for loop, the values are correct, however outside of the while loop the code is printed as null, null and 0. However, the last three values are printed but I am sure that is something to do with my problem.
Anyway, I believe it is to do with scope.
After some searching, I discovered that java is "Pass by Value" instead of "Pass by Reference". I do not really understand this principal, but to my understanding it affects methods in particular, but all of my code is under a single method -- main. I tried to use return inside the for loop and outside but it does not work either!
The way you are initially reading the values in seems quite off: you are placing the corresponding weight and cooking into different indices than the actual mushroom and you are using the index i in completely the wrong way. It should probably be
int i = 0;
while ((line = br.readLine()) != null){
String[] temp = line.split(",");
if(temp.length == 3)
mushroom[i] = temp[0];
weight[i] = Integer.parseInt(temp[1]);
cooking[i] = temp[2];
} else {
// some error handling
}
i++;
}
"When I print the values of the arrays inside of the for loop, the values are correct" is wrong - if you inspect temp the values are correct but mushroom, weight and cooking are never being filled correctly with your code.
Further note:
try using a custom class to hold the associated values instead of dealing with 3 arrays which magically have something to do with each other. Then sort an array of instances of that class
You are writing/over-writing only first three elements in each mushroom, cooking and weight.
As
i < temp.length, i <= 3

compress string into a2b3... etc [duplicate]

This question already has answers here:
Turn String aaaabbbbddd into a4b4d3
(7 answers)
Closed 8 years ago.
Just brushing up on some old java techniques. Currently working through a set of problems, and the one im on is compress strings in the format of aabbcccDDDDeff to a2b2c3d4e1f2. Something funky is happening in my code, pls help sort it out:
public static void main(String[] args) {
String c = "aabbCCCCCdfff";
System.out.println(compress(c));
}
public static String compress(String s) {
String ns = "";
int count = 0;
char temp = 0;
for (int x = 0; x < s.length(); x++) {
if (x == 0) {
ns.concat(String.valueOf(s.charAt(x)));
temp = s.charAt(x);
count++;
} else if (temp == s.charAt(x)) {
count++;
} else {
ns.concat(String.valueOf(count));
count = 0;
ns.concat(String.valueOf(s.charAt(x)));
temp = s.charAt(x);
}
}
return ns;
}
the output is just appearing as null. i'd like to keep my same logic
String.concat (String#concat docs) doesn't mutate your string, it returns a new string that you need to assign to your string variable
ns = ns.concat(theOtherString);
and not this (which is essentially a no-op)
ns.concat(theOtherString);
for example:
ns = ns.concat(String.valueOf(s.charAt(x)));
I would recommend using StringBuilder with its append method for multiple string concatenations. If you choose not to then that is fine if you can argue why the performance benefit doesn't exist, or exists but doesn't apply, in your use case.
Strings in Java are immutable. String.concat does not change the String it's called on, it returns a new String which is the concatination of the object it's called on and the parameter. If you want to accumulate strings, you'd be better served to use a StringBuilder:
StringBuilder ns = new StringBuilder();
int count = 0;
char temp = 0;
for (int x = 0; x < s.length(); x++) {
if (x == 0) {
ns.append(s.charAt(x));
temp = s.charAt(x);
count++;
// rest of code...

extract data from csv file and put to 2D Array - refactoring

I need read data from csv file and much more convinience for me is put there to 2D array (to my mind it's easiest way to work with this "schedule" data).
Each file line contained information in following format:
Instructor, Course, Group, Student, Result
as follows example:
Paul Schwartz,Introduction to Computer Architecture,I1,Ben Dunkin,88
Muhamed Olji,Object Oriented Programming,I4,Mike Brown,73
But my code needs some simplify. But I don't know how to make it easier and ask of You.
Code:
private String[][] fileContent(String pathToCSVFile) {
final int ROWS = 100;
final int COLUMNS = 5;
String fileData[][] = new String[ROWS][COLUMNS];
Scanner scanner = new Scanner(pathToCSVFile);
boolean done = false;
int i, j;
while (!done) {
for (i = 0; i >= 0; i++) {
for (j = 0; j >= 0; j++) {
String str[] = scanner.nextLine().split(",");
for (int element = 0; element < str.length; element++) {
fileData[i][element] = str[element];
if (i >= ROWS) {
Arrays.copyOf(fileData, fileData.length * 2);
}
}
}
}
if (!scanner.hasNextLine()) done = true;
}
return fileData;
}
How to refactor this snippet of code for better simplicity?
Does exist any better way for partially filled array (than Arrays.copyOf(fileData, fileData.length * 2))?
Using openCSV, you can get a list containing all the lines and convert it to an array (or just keep the list):
try (CSVReader reader = new CSVReader(new BufferedReader(
new FileReader(pathToCSVFile)));) {
List<String[]> lines = reader.readAll();
return lines.toArray(new String[lines.size()][]);
}
(using Java 7 try-with-resources syntax)
First of all, be careful with those for loops. They are "almost" undefined loops, because they start with i,j=0, and loop while >=0 (always, until they overflow into a negative number).
And why do you need them anyway? I think with you while and the for(element) you are done, right?
Something like that (I didn't tried, is just to explain the concept)
private String[][] fileContent(String pathToCSVFile) {
final int ROWS = 100;
final int COLUMNS = 5;
String fileData[][] = new String[ROWS][COLUMNS];
Scanner scanner = new Scanner(pathToCSVFile);
boolean done = false;
int i=0;
while (!done) {
String str[] = scanner.nextLine().split(",");
for (int element = 0; element < str.length; element++) {
fileData[i][element] = str[element];
if (i >= ROWS) {
Arrays.copyOf(fileData, fileData.length * 2);
}
}
if (!scanner.hasNextLine())
done = true;
else
i++;
}
return fileData;
}
By the way, why don't you use objects, like an ArrayList? It would make your life easier, so you don't have to worry about memory handling. You just add new objects.
Something like an ArrayList <ArrayList <String>>

Array Not Resizing

I'm trying to resize an Array[] using a method named resize(). I think I've coded the method correctly, however the original array does not resize after running it through the method, and I'm not sure what I'm doing wrong.
I've tested that the newArr[] is in fact twice the length of the oldArr[] and contained the values of the oldArr[], but I can't figure out why it's not taking affect to the wordList[] in the main method.
My assignment is to use Arrays and not Arraylists, so using that is out of the question.
infile = new BufferedReader( new FileReader(infileName) );
while (infile.ready()) {
String s = infile.readLine();
System.out.println(wordList.length);
System.out.println(count);
wordList[count] = s;
if(s.length() > lenOfLongest)
lenOfLongest = s.length();
if(s.length() < lenOfShortest)
lenOfShortest = s.length();
count++;
if(count == wordList.length)
resize(wordList);
}
private static String[] resize( String[] oldArr ) {
String[] newArr = new String[oldArr.length * 2];
System.out.println(newArr.length);
for(int i = 0;i < oldArr.length; i++) {
newArr[i] = oldArr[i];
}
return newArr;
}
if(count == wordList.length)
resize(wordList);
should be:
if(count == wordList.length)
wordList = resize(wordList);
See this answer for more details.
As #pad says in his comment: you don't reassing to wordList.
And your resize() method returns a new array. You should therefore reassing wordList.
As a general note, arrays are not resizable in Java.
Because you are not assign the returned array to anything.Must be as follows.
String[] temp = resize(wordList);

Categories

Resources