1

Is there a cleaner way for doing this ?

public void change(char x)
{
    if(x == 'a')
    {
       return 'b';
    }
    else if(x == 'b')
    {
       return 'a';
    }
    else if(x == 't')
    {
       return 'r';
    }
    else if(x == 'r')
    {
       return 't';
    }
    return 'z';
}

I was wondering if there was anything built into Java so that I can swap pairs of characters like a dictionary in Python or is this the best way to do this?

Community
  • 1
  • 1
user3328784
  • 113
  • 7

6 Answers6

12

Well, it's not making it much shorter, but at least nicer: you could use the switch statement instead of your if-elseif-elseif-... construct.

public char change(char x)
{
    switch (x) {
        case 'a':
            return 'b';
        case 'b':
            return 'a';
        case 't':
            return 'r';
        case 'r':
            return 't';
        default:
            return 'z';
    }
}
Johannes H.
  • 5,875
  • 1
  • 20
  • 40
12

One might try the following:

public char change(char x) {
    final String dictionary = "abtr";
    final String transform = "bart";

    int loc= dictionary.indexOf(x);
    if (loc < 0) {
        return 'z';
    } else {
        return transform.charAt(loc);
    }
}
Mike-O
  • 844
  • 1
  • 11
  • 16
ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
7

"so that i can swap pairs of characters like dictionary in python"

Just use a Map. It's just like a Python Dictionary.

Map<Character, Character> likeADict = new HashMap<Character, Character>();
likeADict.put('a','b');
likeADict.get('a');

You can add and remove values from it at runtime.

jeremyjjbrown
  • 7,772
  • 5
  • 43
  • 55
  • 1
    I consider this an overkill. A `HashMap` has quite some overhead, it's not a particulary small structure... for something that simple, I wouldn't wast the memory and lookup time. BUt, agreed: It's the most flexible solution one can do. – Johannes H. Feb 21 '14 at 22:34
  • 1
    He still needs to check for `null` as return value to return the default (in his case `z`) – Lord M-Cube Feb 21 '14 at 22:35
  • @Mhd.Tahawi No, once is enough. Although the put is idempotent so he could put each pair x times. – jeremyjjbrown Feb 21 '14 at 22:41
  • @jeremyjjbrown, the pairs he has in his question are symmetric. if `a` swaps with `b` then `b` should swap with `a`. so I guess he need to insert the pair and its inverse to work , right ? in order for this to function as a two way map. or no ? – Moha the almighty camel Feb 21 '14 at 22:50
  • @Mhd.Tahawi Sure that's true for any of these solutions. – jeremyjjbrown Feb 21 '14 at 22:51
2

another cool way is using enum, that way adding new swap value is easy, just add a mapping into the enum

public enum swap{
    a('b'),
    b('a'),
    t('r'),     
    r('t'),
    z('z');

    private swap(char c){
        this.value=c;
    }
    public final char value;
}

and the use is:

public char change(char x)
{
   swap swapObject = swap.valueOf(Character.toString(x));
   return swapObject.value;
}
knightsb
  • 337
  • 3
  • 11
  • This has numerous errors. (1) Does not compile. `swap.valueOf(x)` should be `swap.valueOf(Character.toString(x))`. (2) `change` needs to return something. (3) The OP's code changed _all_ characters other than a, b, t, r, to z, and this code doesn't do that. In fact, it doesn't work at all unless `x` is one of those five. (4) This approach only works when all the characters to be swapped are letters. – ajb Feb 21 '14 at 23:46
  • i have changed the code, thanks.i do agree that in case we don't know all the cases we deal with or if we want a default value this approach is not good enough but for this scenario it seems sufficient. – knightsb Feb 22 '14 at 01:46
0

You could use a Map, E.G:

public char change(char x) {
    Map <Character, Character> dictionary = new HashMap<Character, Character>() {{
        put('a', 'b');
        put('b', 'a');
        put('t', 'r');
        put('r', 't');
    }};

    if (dictionary.containsKey(x)) {
        return dictionary.get(x);
    } else {
        return 'z';
    }
}

However I wouldn't bother if its just a few characters. And I would probably make the dictionary a class field.

user1945457
  • 304
  • 1
  • 3
  • 7
-1

The dictionary technic is more flexible but not shorter (like every thing in java). Here is a complete example.

package example;

import java.util.TreeMap;

public class Dictionary {

    static final TreeMap<Character,Character> myDict = new TreeMap();

    static Character choose(TreeMap<Character,Character> dict, 
                            Character x, Character def) {
        Character result = dict.get(x);
        if (result==null) result = def;
        return result;
    }

    public static void main(String[] args) {
        myDict.put('a','b');
        myDict.put('b','a');
        myDict.put('r','t');
        System.out.println(choose(myDict,'a','z'));
        System.out.println(choose(myDict,'b','z'));
        System.out.println(choose(myDict,'r','z'));
        System.out.println(choose(myDict,'X','z'));
    }
}
huckfinn
  • 644
  • 6
  • 23
  • 2
    Why use a TreeMap, which is O(log n), instead of a HashMap, which is O(1), when you don't care about the order of the keys? Also, it should be `new TreeMap<>()`. – JB Nizet Feb 21 '14 at 22:45
  • I like TreeMap .. yes HashMap is also OK.. and new TreeMap<> is possible but not nessesary OR? – huckfinn Feb 21 '14 at 22:50
  • 4
    @huckfinn "I like" is not a particular good reason for a bad design choice... You do realize that different `Map` (as well as different `List`) implementations have different characteristics for a reason? – Johannes H. Feb 21 '14 at 22:52
  • You "like" it? Any good reason? The diamond avoids using raw types and getting unchecked warnings from the compiler. – JB Nizet Feb 21 '14 at 22:52
  • Please stop pitching pennies, dimonds and map types.. Is the solution OK? – huckfinn Feb 21 '14 at 23:00