2017-08-27 13 views
0

文字列を長桁に変換します。 私はこれを行う:ストリームがロングタイプで正しく処理されない

String line = "eRNLpuGgnON"; 
char[] chars = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890-_".toCharArray(); 
Map<Character, Integer> charToInt = 
      IntStream.rangeClosed(0, chars.length - 1) 
        .boxed() 
        .collect(Collectors 
          .toMap(i -> (chars[i]), i -> i)); 

long l = line.chars() 
      .mapToObj(i -> (char) i) 
      .map(charToInt::get) 
      .reduce((int) 0L, ((a, b) -> a * chars.length + b)); 
System.out.println(l); 

私は記号でマップに対応するインデックスを取り、乗算と加算の最短操作を行います。

例。私はeRNLpuGgnONという行を持っています。これらのシンボルはMapで、このような値が設定されています

e=2 
R=29 
N=50 
.... 

アルゴリズムは非常に簡単です:

0*64+2 = 2 
2*64 + 29 = 157 
157*64 + 50 = 10098 
........ 

最後に、私は、この値を取得する必要があります。

2842528454463293618 

をしかし、私は取得しますこの値:

-1472624462 

そして、lineの値が十分に短い場合、すべて正常に動作します。私はロングの価値を正しく働かない理由を理解できません。

+1

あなたの減少は(https://docs.oracle.com/javase/8/docs/api/java/util/stream/ [連想]ではありません:あなたのcharToIntマップで長い移動するための方法される使用package-summary.html#Associativity)。 – shmosel

+0

@shmosel、どうすれば修正できますか? –

答えて

1

問題は、reduce操作で整数を使用しているため、間違った結果をもたらすInteger.MAX_VALUEに達することです。

Map<Character, Long> charValues = IntStream.range(0, chars.length) 
       .boxed() 
       .collect(Collectors.toMap(i -> chars[i], Long::valueOf)); 

long l = line.chars() 
     .mapToObj(i -> (char) i) 
     .map(charValues::get) 
     .reduce(0L, (a, b) -> a * chars.length + b); 

System.out.println(l); 
// prints "2842528454463293618" 
関連する問題