0

I have this code that filters a String str, keeping only some chars, resulting in the reduced String fStr. The subtlety is that I only keep a target char, if it is not equal to the last char in fStr:

ArrayList<Character> targetChars = //{a, b, c};
String str = "axxbxxxxbxbxcxa", fStr = "";

for(int i = 0, s = 0 ; i < str.length() ; i++) {
    char c = str.charAt(i);
    if(targetChars.contains(c)) {
        if(s > 0 && fStr.charAt(s-1) != c) {
            fStr += c;
            s++;
        }
    }
}  

fStr → "abca"

In the innermost if statement, I have to include s > 0 before fStr.charAt(s-1) != c, otherwise the latter will throw an OutOfBounds exception the first time targetChars.contains(c) is true. But only the first time, it annoys me that the loop will always check that I won't be out of bounds, given that it only has to do it once. I know I could do something like that:

ArrayList<Character> targetChars = //{a, b, c};
String str = "auebskrubnbocpa", fStr = "";
int i = 0, s = 0;   

for(; i < str.length() ; i++) {
    char c = str.charAt(i);
    if(targetChars.contains(c)) {
            fStr += c;
            s++;
            i++;
            break;
    }
}

for(; i < str.length() ; i++) {
    char c = str.charAt(i);
    if(targetChars.contains(c)) {
        if(fStr.charAt(s-1) != c) {
            fStr += c;
            s++;
        }
    }
}

But is there a more elegant and less annoying way to dynamically truncate a conditional statement?

Maljam
  • 6,244
  • 3
  • 17
  • 30
  • after you record each char, why don't you store that in some variable and keep referring to it? – Constantin Mar 27 '16 at 01:53
  • @Constantin I understand what you mean, that would work here. But this is just an example, I was wondering if, in general, there is some mechanism to deal with situation like that, where the initial condition is more complicated – Maljam Mar 27 '16 at 01:56
  • if you dont want to use s, you might try something like if(fStr.charAt(fStr.length() - 1) != c) ... but you will have to take care for empty fStr – Constantin Mar 27 '16 at 02:13
  • @Constantin you would still have to check `fStr.length() != 0` – Maljam Mar 27 '16 at 02:14
  • yes that's correct ... are you just lkooking for an elegant solution? – Constantin Mar 27 '16 at 02:16

3 Answers3

2

Is there a way to dynamically change conditions in if statement in Java?

No there isn't. The original version of your code is the best from a readability perspective.

However, if you are concerned about efficiency, then you should be using a StringBuilder rather than fStr += c.

Also a char[] and an explicit for loop is likely to be faster than ArrayList<Character>.contains.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

Here is how I would do it, but not sure if it suits your needs

public class Example {

public static void main(String[] args) {
    char[] targetChars = {'a', 'b', 'c'};
    String str = "axxbxxxxbxbxcxa", fStr = " ";

    for(int i = 0 ; i < str.length() ; i++) {
        char c = str.charAt(i);
        if(isAcceptableChar(c, targetChars)) {

            if(fStr.charAt(fStr.length() - 1) != c) {
                fStr = fStr.trim() + c;
            }
        }
    }

    System.out.println(fStr);       
}


private static boolean isAcceptableChar(char newChar, char[] targetChars) {
    boolean value = false;

    for(char ch : targetChars){
        if(ch == newChar) {
            value = true;
            break;
        }
    }
    return value;
}   
}
Constantin
  • 1,506
  • 10
  • 16
0

Sure there is, just call a function that returns a boolean value that you use in your if condition. Different functions could be called at different times by using a function pointer.

dgsomerton
  • 105
  • 5
  • That doesn't answer the question, because you are saying to just bury the condition in a method, that doesn't address the issue, the method would have to do same thing internally... – Maljam Mar 27 '16 at 02:09
  • I see you missed the part about using a function pointer and changing the function that the pointer points at, in response to certain conditions. This is a standard idiom. – dgsomerton Mar 27 '16 at 02:11
  • then could you please expand, I don't know what a function pointer is in Java? Could you show an example? – Maljam Mar 27 '16 at 02:13
  • Java does not know the concept of function pointers. I think your are talking about C. – cwschmidt Mar 27 '16 at 02:40
  • The concept of function pointers is simulated in Java using Interface class. – dgsomerton Mar 27 '16 at 03:18
  • I have an example, but it will not post. I get an error saying it is too long. Here is the gist: ' public interface Condition { boolean eval( String s, int index, char c ); } public static final Condition c1 = new Condition() { public boolean eval( String s, int index, char c ) { return index > 0 && s.charAt(index-1) != c; } }; public static final Condition c2 = new Condition() { public boolean eval( String s, int index, char c ) { return s.charAt(index-1) != c; } }; ` – dgsomerton Mar 27 '16 at 03:30