This loop breaks if uncomment 2 commented string, cannot figure out why it happens, help plz:
private static String findAll(String cell, ArrayList<String> hrange, ArrayList<String> vrange, List<String> cellrange, Integer cycle){
cellrange.add(cell);
String color = XldocReader.xlCells.get(cell);
String[] chkeys = cell.split("\\$");
String chLetter = chkeys[1];
Integer chNumber = Integer.parseInt(chkeys[2]);
boolean rcnext = false;
boolean rcprev = false;
Iterator<String> ite = hrange.iterator();
while ( ite.hasNext() ) {
String candidate = ite.next();
String value = XldocReader.xlCells.get(candidate);
String[] ckeys = candidate.split("\\$");
String cLetter = ckeys[1];
int n = getKeyByValue(chLetter);
String next = cell.replaceAll(chLetter+"", columns.get(n+1) +"");
String cnext = XldocReader.xlCells.get(next);
String prev = cell.replaceAll(chLetter+"", columns.get(n-1) +"");
String cprev = XldocReader.xlCells.get(prev);
//rcnext = cnext.equals(color);
//rcprev = cprev.equals(color);
...
}
return cellrange.toString();
}
it should find equals strings and run recursively check again but on first check it's breaks and nothing check more...
I would make the loop
for(String candidate : hrange) {
}
And I would step through the code in a debugger to see exactly what it is doing as I suspect you program isn't doing what you think it is.
What do you mean by breaks? What is the Exception and on which line does it occur? Does it match what you see in the debugger?
I suspect the problem is in the code you have labelled as ...
Can you give us more info? What the error is? How it breaks? etc. Also, print out the results of color and cnext, cprev right before it breaks.
My guess is those are not legit strings. And you are trying to run an equals method on something that is not a legit string.
Related
I am reading data from a file, one line at a time. The number of elements in the line can vary. I am using Java 8.
public boolean display (Integer code, String line) {
String[] strArray = line.split(Constant.sep);
String name = strArray[0];
String address = strArray[1];
String country = strArray[2];
//Do Something Scenario (if only name is Not Null, OR if name & address are not null or ....
}
In the above case, not all the fields are necessary for the follow up execution.
However, strArray goes out of bound in the above case, say, when e.g. only field "name" is present. I understand, why this happens. Is there a solution to get around this?
I would prefer to simplify the code and not have to create separate code for each situation or build a complex If/else logic for each combination. The value "code" is a helper that tells the method that what fields are present in the "String line".
Use if statements.
String name = “default”;
String address = “default”;
String country = “default”;
int length = strArray.length;
if(length > 1)
name = strArray[0];
if(length > 2)
address = strArray[1];
if(length > 3)
country = strArray[2];
This works because the code “falls through” to each if statement. If the length is 2, then the third if statement is not executed but the first two are. This allows for you to avoid repeating yourself and using a long if statement structure.
As long as you are using java8, I guess this would be useful, this is a simple try with Optional:
public boolean display(Integer code, String line) {
String[] strArray = line.split(Constant.sep);
String[] strArrayTemp = new String[3];
System.arraycopy(strArray, 0, strArrayTemp, 0, strArray.length);
String name = "";// or anything that represents your default value
String address = "";
String country = "";
if (Optional.ofNullable(strArrayTemp[0]).isPresent())
name = strArrayTemp[0];
if (Optional.ofNullable(strArrayTemp[1]).isPresent())
address = strArrayTemp[1];
if (Optional.ofNullable(strArrayTemp[2]).isPresent())
country = strArrayTemp[2];
//complete your logic ...
return true; // I guess
}
the variable TEST is equal to this
lazar108#hotmail.com_Hd_s lazar108#hotmail.com_Update_on the lazar108#hotmail.com_Ksks_ajsj
i want to pull each "product" out so i have an ArrayList equal to this
lazar108#hotmail.com_Hd_s
lazar108#hotmail.com_Update_on
lazar108#hotmail.com_Ksks_ajsj
Right now the only thing in my array list is lazar108#hotmail.com_Hd_s
How can i pull each "product" from the one variable (TEST) in a loop and add it to the ArrayList?
My code so far:
String TEST = result;
ArrayList<String> Products = new ArrayList<>();
boolean flag = true;
while(flag == true){
Products.add(TEST.substring(0, TEST.indexOf(' ')));
TEST = TEST.substring(TEST.indexOf(' ') + 1);
if(TEST.equals("")){
flag = false;
}else{
TEST = TEST.substring(1);
}
}
Your one step away from doing it. After the first iteration of your while loop, you do retrieve lazar108#hotmail.com_Hd_s, but after that the loop runs infinitely because the other parts of the string are not being accessed. The solution is to cut out the part you retrieved from the string each time you add it to Products. I should also note that this will only work if TEST ends with a space " ". Here is a way to approach this.
String TEST = result;
ArrayList<String> Products = new ArrayList<>();
boolean flag = true;
while(flag == true){
Products.add(TEST.substring(0,TEST.indexOf(' ')));
TEST = TEST.substring(TEST.indexOf(' '));//cutting the last email added from the string
if(TEST.equals(" ")){
flag = false;
}
else{
TEST = TEST.substring(1); //remove that space so that it doesn't get
//counted again in the next iteration
}
}
Seeing your input string doesn't simply have email separated by white space, I suggest you use Pattern and Matcher. First you need to define the email's pattern (you can google it), then use the example in this : http://www.tutorialspoint.com/java/java_regular_expressions.htm
An alternative one line solution using String.split() function:
List<String> products = Arrays.asList(TEST.split(" "));
I have String Array of a good couple hundred lines of code. I have two other String Arrays, one with values I want to replace, and the other with the value I want it to replace to. I need to go through each line of the original code and check each line if it contains anything that I need to replace, and if it does, replace it. I want to replace it to a totally different String Array, so that the original is still left unchanged. This is what I have, but it's not exactly working.
for(int i=0; i<originalCode.length; i++) {
if( originalCode[i].contains("| "+listOfThingsToReplace[i]) ) {
newCode[i]=originalCode[i].replaceAll(("| "+listOfThingsToReplace[i]), ("| "+listOfReplacingThings[i]));
}
}
Obviously I need more counting variables somewhere (especially because originalCode.length !=listOfThingsToReplace.length), but I can't figure out where. Would I need more for loops? I tired doing that... but "Exception in thread "main" java.lang.OutOfMemoryError: Java heap space"... Any help please?
I think this should do the trick if I'm understanding the problem correctly
// New Code Array
String[] newCode = new String[originalCode.length];
for (int i=0; i<originalCode.length; i++) {
// New Code Line
String newCodeLine = originalCode[i];
// Iterate through all words that need to be replaced
for (int j=0; j<listOfThingsToReplace.length; j++) {
// String to replace
String strToReplace = listOfThingsToReplace[j];
// String to replace with
String strToReplaceWith = (j >= listOfReplacingThings.length) ? "" : listOfReplacingStrings[j];
// If there is a string to replace with
if (strToReplaceWith != "") {
// then replace all instances of that string
newCodeLine = newCodeLine.replaceAll(strToReplace, strToReplaceWith);
}
}
// Assign the new code line to our new code array
newCode[i] = newCodeLine;
}
Say I got a string from a text file like
"Yes ABC 123
Yes DEF 456
Yes GHI 789"
I use this code to split the string by whitespace.
while (inputFile.hasNext())
{
String stuff = inputFile.nextLine();
String[] tokens = stuff.split(" ");
for (String s : tokens)
System.out.println(s);
}
But I also want to assign Yes to a boolean, ABC to another string, 123 to a int.
How can I pick them up separately? Thank you!
boolean b=tokens[0].equalsIgnoreCase("yes");
String name=tokens[1];
int i=Integer.parseInt(tokens[2]);
Could you clarify what the exact purpose of what you're doing is? You can refer to the separate Strings with tokens[i] with i being the index. You could throw these into a switch statement (since Java 7) and match for the words you're looking for. Then you can take further action, i.e. convert the Strings to Booleans or Ints.
You should consider checking the input to be valid too even if you are expecting the file to always have those 3 words separated by a space.
Create Class Line and List<Line> that will store all your file into list:
public class Line{
private boolean mFlag = false;
private int mNum = 0;
private String mStr;
public Line(String stuff) {
String[] tokens = stuff.split("[ ]+");
if(tokens.length ==3){
mFlag=tokens[0].equalsIgnoreCase("yes");
mNum=Integer.parseInt(tokens[1]);
mStr=tokens[3];
}
}
}
and call it:
public static void main(String[] args) {
List<Line> list = new ArrayList<Line>();
Line line;
while (inputFile.hasNext())
{
String stuff = inputFile.nextLine();
line = new Line(stuff);
list.add(line);
}
}
If your input String is going to be in the same format always i.e. boolean,String ,int then you can access the individual indices of token array and convert them to your specified format
boolean opinion = tokens[0].equalsIgnoreCase("yes");
String temp = token[1];
int i = Integer.parseInt(token[2])
But you might require to create an array or something that stores the values for consecutive inputs that user does otherwise these variables would be over ridden for every new input from user.
When I use System.out.println to show the size of a vector after calling the following method then it shows 1 although it should show 2 because the String parameter is "7455573;photo41.png;photo42.png" .
private void getIdClientAndPhotonames(String csvClientPhotos)
{
Vector vListPhotosOfClient = new Vector();
String chainePhotos = "";
String photoName = "";
String photoDirectory = new String(csvClientPhotos.substring(0, csvClientPhotos.indexOf(';')));
chainePhotos = csvClientPhotos.substring(csvClientPhotos.indexOf(';')+1);
chainePhotos = chainePhotos.substring(0, chainePhotos.lastIndexOf(';'));
if (chainePhotos.indexOf(';') == -1)
{
vListPhotosOfClient.addElement(new String(chainePhotos));
}
else // aaa;bbb;...
{
for (int i = 0 ; i < chainePhotos.length() ; i++)
{
if (chainePhotos.charAt(i) == ';')
{
vListPhotosOfClient.addElement(new String(photoName));
photoName = "";
continue;
}
photoName = photoName.concat(String.valueOf(chainePhotos.charAt(i)));
}
}
}
So the vector should contain the two String photo41.png and photo42.png , but when I print the vector content I get only photo41.png.
So what is wrong in my code ?
The answer is not valid for this question anymore, because it has been retagged to java-me. Still true if it was Java (like in the beginning): use String#split if you need to handle csv files.
It's be far easier to split the string:
String[] parts = csvClientPhotos.split(";");
This will give a string array:
{"7455573","photo41.png","photo42.png"}
Then you'd simply copy parts[1] and parts[2] to your vector.
You have two immediate problems.
The first is with your initial manipulation of the string. The two lines:
chainePhotos = csvClientPhotos.substring(csvClientPhotos.indexOf(';')+1);
chainePhotos = chainePhotos.substring(0, chainePhotos.lastIndexOf(';'));
when applied to 7455573;photo41.png;photo42.png will end up giving you photo41.png.
That's because the first line removes everything up to the first ; (7455573;) and the second strips off everything from the final ; onwards (;photo42.png). If your intent is to just get rid of the 7455573; bit, you don't need the second line.
Note that fixing this issue alone will not solve all your ills, you still need one more change.
Even though your input string (to the loop) is the correct photo41.png;photo42.png, you still only add an item to the vector each time you encounter a delimiting ;. There is no such delimiter at the end of that string, meaning that the final item won't be added.
You can fix this by putting the following immediately after the for loop:
if (! photoName.equals(""))
vListPhotosOfClient.addElement(new String(photoName));
which will catch the case of the final name not being terminated with the ;.
These two lines are the problem:
chainePhotos = csvClientPhotos.substring(csvClientPhotos.indexOf(';') + 1);
chainePhotos = chainePhotos.substring(0, chainePhotos.lastIndexOf(';'));
After the first one the chainePhotos contains "photo41.png;photo42.png", but the second one makes it photo41.png - which trigers the if an ends the method with only one element in the vector.
EDITED: what a mess.
I ran it with correct input (as provided by the OP) and made a comment above.
I then fixed it as suggested above, while accidently changing the input to 7455573;photo41.png;photo42.png; which worked, but is probably incorrect and doesn't match the explanation above input-wise.
I wish someone would un-answer this.
You can split the string manually. If the string having the ; symbol means why you can do like this? just do like this,
private void getIdClientAndPhotonames(String csvClientPhotos)
{
Vector vListPhotosOfClient = split(csvClientPhotos);
}
private vector split(String original) {
Vector nodes = new Vector();
String separator = ";";
// Parse nodes into vector
int index = original.indexOf(separator);
while(index>=0) {
nodes.addElement( original.substring(0, index) );
original = original.substring(index+separator.length());
index = original.indexOf(separator);
}
// Get the last node
nodes.addElement( original );
return nodes;
}