Workaround for declaring array in an if condition - java

I have a problem with this part of the code where I want to be able to declare an array and the size of which should be the corresponding no of splits in the string.
Or do I need to count the no of commas in the string and allocate size accordingly or is there a better solution.
String MapPath2[];
if(type.equals("comparative"))
MapPath2[]=args[1].split(",");
I haven't had a chance to code in java in the recent past. Please spare me if it is a silly question and guide me as a noob. Appreciate your help.

You don't need to declare the size, what you have is fine if you remove the extra []:
String MapPath2[];
if(type.equals("comparative"))
MapPath2=args[1].split(",");
The array split gives back to you has the appropriate size. If you need to know the resulting size, use MapPath2.length (after assigning it).
You'd probably want to do something in the else as well, so that MapPath2 has a definite value either way:
String MapPath2[];
if(type.equals("comparative"))
MapPath2=args[1].split(",");
else
MapPath2=null;
or more concisely:
String MapPath2[];
MapPath2 = type.equals("comparative") ? args[1].split(",") : null;
(Instead of the nulls there, if having an empty array is preferred for subsequent logic as is sometimes handy, replace null with new String[0] above and below. Other times, it's more handy to have the null as a "no data" flag.)
Side note: There are some overwhelmingly common code style conventions in the Java world that you would be best advised to use in your code:
Variable names should start with a lower case letter, so as not to be confused with class names.
The [] should go with the type name rather than the variable name.
Always use {} even when the body of an if or else is only one line.
Put spaces around operators and keywords for ease of reading.
Applying those:
String[] mapPath2;
if (type.equals("comparative")) {
mapPath2 = args[1].split(",");
}
else {
mapPath2 = null;
}
Many people also put the else on the same line as the }, so:
String[] mapPath2;
if (type.equals("comparative")) {
mapPath2 = args[1].split(",");
} else {
mapPath2 = null;
}
Or again, more concisely:
String[] mapPath2;
mapPath2 = type.equals("comparative") ? args[1].split(",") : null;

You can use List instead of Array if you don't know what size it needs be.
Then you can use
List<String> list = new ArrayList<>();
if(type.equals("comparative")){
Collections.addAll(list, args[1].split(","));
}

Related

How can I fix my code to find a certain character in an array and make changes to that array

while (scan_file.hasNext()) {
String b = scan_file.nextLine();
// checks if string b contains the tag <h>
if (b.contains("<h>")) {
char arrayString[] = b.toCharArray();
for (int i = 0; i < arrayString.length; i++) {
if (arrayString[i] == '<') {
arrayString[i] = arrayString[i + 2];
}
System.out.print(arrayString[i]);
}
}
}
What I was expecting the program to do was(for now) iterate through the while loop and store each line as string 'b'.
I want to check if that string b contains a certain string like <h> for this example. And I want to convert string b into an array if it contains said string like <h> and iterate through that array to check for '<' and move the array up 2 spaces.
For example, string b had <h>hello, I wanted to eventually print hello because the program would have moved up 2 elements.
I feel like I got the loops and general idea on how I want to tackle the problem.. but when I ran the program, nothing printed so I don't know if I did the loops and if statements correctly.
I really don't know how to word my problem well, so bear with me and I'm sorry in advance.
All feedbacks are greatly appreciated (:
System.out.print(arrayString[i]); just print the ith character of arrayString, it's definitely not what you want.
In fact you don't have to convert a String to char[], String has many utils method can help you with your goal.
I won't give you full code , but I can give you some tips.
You can use String.indexof('<') to find the index of '<'.
You can use String.subString(startIndex) to get the subString start with the specified index.
Suppose your code scan_file.hasNext() and scan_file.nextLine() is work well. You can try code below to remove all from current line:
if (b != null && b.contains("<h>")) {
System.out.println(b.replaceAll("<h>", ""));
}

Issue with .equals()

Following is a small section of the code I am using, along with the syntax of the text file I am using. (I am fairly sure both are grossly overcomplicated, but I am not exactly sure how to simplify them.)
while((line = bufferedReader.readLine()) != null)
{
if(line.split("##")[0].equals(lineNumber))
{
numberOfLines = Integer.parseInt(line.split("##")[1]);
spaceSkip = 1;
worked = 0;
}
if(spaceSkip == 0)
{
if(numberOfLines > 0)
{
System.out.println(line);
numberOfLines--;
}
}
spaceSkip = 0;
}
And the format of the text file is:
1##2##3##0
Text goes below it,
and can span multiple lines.
The 3 and 0 do not come into play here. The intent is for the program to search for the number selected and match it to the first number, 1 in this case. The second number is the number of lines to read. In the code, I have "spaceSkip" so that it does not read the indexing line.
Explanations aside, the issue I am having is that line.split("##")[0].equals(lineNumber) seems to be reading false. I have printed both out to the screen at the same time, and both equal 1, but it is still returning an error message I included. ("worked = 0;" is what keeps the error from triggering.) I am certain it is a stupidly simple mistake I am making here, but I still am unable to figure it out. Thank you in advance.
Whenever a comparison doesn't return what you think it should, check that the types are what you think they are.
String#split returns an array of Strings. For your given input the first element of that array will be "1". If lineNumber is something other than a String, say an int, then equals will still work (the primitive int gets autoboxed to a java.lang.Integer, which is a subclass of java.lang.Object, which is the type the equals method takes as a parameter), but the comparison ("1".equals(1)) will always return false. JavaScript is OK with equating a string and an int ("1" == 1 returns true), but Java is not.
The easiest fix would be to convert the lineNumber to a String, by calling String#valueOf passing in lineNumber. It would be better to convert lineNumber to a String than try to convert the split output to an Integer, because the Integer parsing could fail on bad input, and I'd rather avoid having to manage that possibility.
The cut-n-pasting of the split call is unfortunate mostly because of redundancy, you should do the split once into a local variable like:
String[] parts = line.split("##");
if (parts[0].equals("1")) {
numberOfLines = Integer.parseInt(parts[1]);
...
Without seeing the initialization of the variables it is hard to tell, but it is possible that you are comparing a String to an Integer in this if statement.
You may want to try casting the second argument to a String as follows.
if(line.split("##")[0].equals(String.valueOf(lineNumber)))

Splitting string algorithm in Java

I'm trying to make the following algorithm work. What I want to do is split the given string into substrings consisting of either a series of numbers or an operator.
So for this string = "22+2", I would get an array in which [0]="22" [1]="+" and [2]="2".
This is what I have so far, but I get an index out of bounds exception:
public static void main(String[] args) {
String string = "114+034556-2";
int k,a,j;
k=0;a=0;j=0;
String[] subStrings= new String[string.length()];
while(k<string.length()){
a=k;
while(((int)string.charAt(k))<=57&&((int)string.charAt(k))>=48){
k++;}
subStrings[j]=String.valueOf(string.subSequence(a,k-1)); //exception here
j++;
subStrings[j]=String.valueOf(string.charAt(k));
j++;
}}
I would rather be told what's wrong with my reasoning than be offered an alternative, but of course I will appreciate any kind of help.
I'm deliberately not answering this question directly, because it looks like you're trying to figure out a solution yourself. I'm also assuming that you're purposefully not using the split or the indexOf functions, which would make this pretty trivial.
A few things I've noticed:
If your input string is long, you'd probably be better off working with a char array and stringbuilder, so you can avoid memory problems arising from immutable strings
Have you tried catching the exception, or printing out what the value of k is that causes your index out of bounds problem?
Have you thought through what happens when your string terminates? For instance, have you run this through a debugger when the input string is "454" or something similarly trivial?
You could use a regular expression to split the numbers from the operators using lookahead and lookbehind assertions
String equation = "22+2";
String[] tmp = equation.split("(?=[+\\-/])|(?<=[+\\-/])");
System.out.println(Arrays.toString(tmp));
If you're interested in the general problem of parsing, then I'd recommend thinking about it on a character-by-character level, and moving through a finite state machine with each new character. (Often you'll need a terminator character that cannot occur in the input--such as the \0 in C strings--but we can get around that.).
In this case, you might have the following states:
initial state
just parsed a number.
just parsed an operator.
The characters determine the transitions from state to state:
You start in state 1.
Numbers transition into state 2.
Operators transition into state 3.
The current state can be tracked with something like an enum, changing the state after each character is consumed.
With that setup, then you just need to loop over the input string and switch on the current state.
// this is pseudocode -- does not compile.
List<String> parse(String inputString) {
State state = INIT_STATE;
String curr = "";
List<String> subStrs = new ArrayList<String>();
for(Char c : inputString) {
State next;
if (isAnumber(c)) {
next = JUST_NUM;
} else {
next = JUST_OP;
}
if (state == next) {
// no state change, just add to accumulator:
acc = acc + c;
} else {
// state change, so save and reset the accumulator:
subStrs.add(acc);
acc = "";
}
// update the state
state = next;
}
return subStrs;
}
With a structure like that, you can more easily add new features / constructs by adding new states and updating the behavior depending on the current state and incoming character. For example, you could add a check to throw errors if letters appear in the string (and include offset locations, if you wanted to track that).
If your critera is simply "Anything that is not a number", then you can use some simple regex stuff if you dont mind working with parallel arrays -
String[] operands = string.split("\\D");\\split around anything that is NOT a number
char[] operators = string.replaceAll("\\d", "").toCharArray();\\replace all numbers with "" and turn into char array.
String input="22+2-3*212/21+23";
String number="";
String op="";
List<String> numbers=new ArrayList<String>();
List<String> operators=new ArrayList<String>();
for(int i=0;i<input.length();i++){
char c=input.charAt(i);
if(i==input.length()-1){
number+=String.valueOf(c);
numbers.add(number);
}else if(Character.isDigit(c)){
number+=String.valueOf(c);
}else{
if(c=='+' || c=='-' || c=='*' ||c=='/'){
op=String.valueOf(c);
operators.add(op);
numbers.add(number);
op="";
number="";
}
}
}
for(String x:numbers){
System.out.println("number="+x+",");
}
for(String x:operators){
System.out.println("operators="+x+",");
}
this will be the output
number=22,number=2,number=3,number=212,number=21,number=23,operator=+,operator=-,operator=*,operator=/,operator=+,

Checking the end of a string in Java multiple times?

So in Java, I know that str.endsWith(suffix) tests if str ends with something. Let's say I have a text with the line "You are old" in it. How would I take the "old" and set it as a variable so I can print it out in the console?
I know I could do:
if(str.endsWith("old")){
String age = "old";
}
But then I'm going to have more options, so then I'd have to do:
if(str.endsWith("option1")){
String age = "option1";
}
if(str.endsWith("option2")){
String age = "option2";
}
...
Is there a more efficient and less verbose way to check the end of strings over writing many, possibly hundreds, of if statements
Format:
setting: option
setting2: option2
setting3: option3 ...
Regardless of what "option" is, I want to set it to a variable.
If you are working with sentences and you want to get the word, do
String word = str.substring(str.lastIndexOf(" "));
You may need a +1 after the lastIndexOf() to leave the space out.
Is that what you are looking for?
Open your file and read the line with the readLine() method. Then to get the last word of the string you can do as it is suggested here
You mean like:
String phrase = "old";
if(str.endsWith(old)){
Is this what you're looking for?
List<String> suffixes = new ArrayList<String>();
suffixes.add("old");
suffixes.add("young");
for(String s: suffixes)
{
if (str.endsWith(s))
{
String age = s;
// .... more of your code here...
}
}
If you're worried about repeating very similar code, the answer is always (99%) to create a function,
So in your case, you could do the following:
public void myNewFunction(String this, String that){
if(this.endsWith(that)){
String this = that;
}
}
...
String str = "age: old";
myNewFunction(str, "old"); //Will change str
myNewFunction(str, "new"); //Will NOT change str
And if that is too much, you can create a class which will do all of this for you. Inside the class, you can keep track of a list of keywords. Then, create a method which will compare a given word with each keyword. That way, you can call the same function on a number of strings, with no additional parameters.
You could use this Java code to solve your problem:
String suffix = "old";
if(str.endsWith(suffix)) {
System.out.println(suffix);
}

java code style question - for loops

Is the following code clear and easy to read?
public void createDatabase() throws SQLException, IOException {
SQLiteDatabase database = dbStore.getDatabase();
LineNumberReader scriptInputReader = new LineNumberReader(new InputStreamReader(getClass().getResourceAsStream(SCRIPT_CREATE)));
for(String line; (line = scriptInputReader.readLine()) != null;) {
database.execSQL(line);
}
}
I write a lot of "for" loops like the one above. For me it looks clear - it shows the temporary variable ("line") used in the loop, limits it's scope and points out when the loop ends (when "readLine" returns "null"). I wonder if other programmers will hate me for those...
or this one:
SQLiteDatabase database = dbStore.getDatabase();
Cursor cursor = database.query("PINS", new String [] {"ID", "X", "Y"}, null, null, null, null, "ID");
if(cursor.moveToFirst()) {
for(; !cursor.isAfterLast(); cursor.moveToNext()) {
(...)
}
}
cursor.close();
Are things like the above just "neat" or already a Java-puzzles?
I'd opt for:
String line = null;
while((line = scriptInputReader.readLine()) != null) {
... do stuff with line
}
This is clear and straightforward.
I like what you've done, but I would make one small change:
for(String line = scriptInputReader.readLine(); line != null; line = scriptInputReader.readLine()) {
database.execSQL(line);
}
This separates the iteration action from the loop termination condition. Also, unlike the "while" version, it limits the scope of the line variable to the loop - narrowing scope as much as possible is good coding practice.
Also, code style checkers usually consider assignments nested within tests as "poor style". To be clear, your code is a bit like this:
for (int i = -1; ++i < max;) { // don't do this: increment action inside condition section
// some code
}
I would use a while loop
String line = scriptInputReader.readLine();
while(line != null){
//do stuff
line = scriptInputReader.readLine();
}
I would feel more at ease with while.
The first one is not that bad as it is because it is easy to understand what the loop does, but if you add more logic in the middle of the loop and the operation is complicated it will become more difficult (because people will think:'hey, if he wanted just to read a file he would have used a while, so there must be some trick').
The second one (the for doing at the work, and no code inside the loop) is awful and probably in a not so distant future someone will say: 'Hey, there was a loop here and the contents were removed, but they forgot to remove the loop! I can optimize that by removing the for altogether').
I think there are two different schools of thought here. The one as shown by Jarek Potiuk that prefers to use for/while loops for different purposes, ie. a for loop should be used when you know the range of your loop in advance (for (;i < arr.length(); i++)) while a while is preferred for unlimited situations.
But then there's the other line of thought that uses only one kind of loop and at that the for loop because it's more versatile. The Java SDK for example uses for loops pretty extensively in unlimited situations (eg linked lists).
But then you should really write the for loop like Bohemian does - much clearer.
Some prefer to use a while-loop when you do not know when the loop will terminate. For example reading through a file.
Jarek Potiuk's solution works, however I prefer something like this:
String line = scriptInputReader.readLine();
while(line != null)
{
... do stuff with line
line = scriptInputReader.readLine();
}
It is a little bit more code, but I have to agree with Bohemian:
code style checkers usually consider
assignments nested within tests as
"poor style"

Categories

Resources