10

I have a sequence of English and Arabic text that should be printed in an aligned way.

For example:

List<Character> ar = new ArrayList<Character>();
ar.add('ا');
ar.add('ب');
ar.add('ت');

List<Character> en = new ArrayList<Character>();
en.add('a');
en.add('b');
en.add('c');

System.out.println("ArArray: " + ar);
System.out.println("EnArray: " + en);   

Expected Output:

ArArray: [ت, ب, ا] // <- I want characters to be printed in the order they were added to the list
EnArray: [a, b, c]

Actual Output:

ArArray: [ا, ب, ت] // <- but they're printed in reverse order
EnArray: [a, b, c]

Is there a way to print Arabic characters in left-to-right direction without explicitly reversing the list before output?

Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67
vanilla
  • 331
  • 3
  • 14
  • 1
    If the "actual output" part above is correct, it seems the array is reversing its elements on its own. – George T Apr 16 '15 at 10:19
  • 1
    @SashaSalauyou please check the actual and expected outputs again. I intended to print it normally from left to right as English letters but actually it has been reversed in the output. – vanilla Apr 16 '15 at 10:22
  • @GeorgeT yes it has been reversed but I don't want it to be reversed because the text is not displayed as aligned. – vanilla Apr 16 '15 at 10:24
  • @vanilla i m just curious why do you need this ? – Anarki Apr 16 '15 at 10:25
  • Your question is very ambiguous, please add a better description of your problem -- "without having to reverse the array." Also, that is a List, not an Array. – Mr. Polywhirl Apr 16 '15 at 10:25
  • @Anarki I need both arrays to be displayed according the insertion order not according to the nature of the language. So, I just need to force the output stream to print it from left to right and don't take in consideration the actual nature of the language as a right to left language – vanilla Apr 16 '15 at 10:29
  • @Mr.Polywhirl actually it's an array list :), I need to reserve the insertion order in the print output and not to reverse it. – vanilla Apr 16 '15 at 10:32

1 Answers1

11

You need to add the left-to-right mark '\u200e' before each RTL character to make it be printed LTR:

public String printListLtr(List<Character> sb) {
    if (sb.size() == 0) 
        return "[]";
    StringBuilder b = new StringBuilder('[');
    for (Character c : sb) {
        b.append('\u200e').append(c).append(',').append(' '); 
    }
    return b.substring(0, b.length() - 2) + "]";
}
Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67
  • Would it work without a self made loop if you write System.out.println("\u200eArArray: " + ar). I haven't got a terminal that supports AR so I can't try myself. – Torben Apr 16 '15 at 10:45
  • @Torben I tried to add it just before entire output, but it doesn't work. I succeeded only when adding it before each arabic character. – Alex Salauyou Apr 16 '15 at 10:46
  • Nice answer. You could also create a new class which extends ArrayList and overwrites ".toString()" with that code. – JanTheGun Apr 16 '15 at 11:29
  • @JanTheGun `elementData` array in `ArrayList` is private thus cannot be accessed from child class. Of course, I can gather elements by iterator, but... It is idea for those who need this. – Alex Salauyou Apr 16 '15 at 11:33
  • Hm, I just tried it out and it works. In the overwritten toString() Method I used "this" instead of "sb.size". I still wonder though why it doesn't revert the english version (Which is good in this case). – JanTheGun Apr 16 '15 at 11:45