Java - забавное преобразование строки (4 символа) в int и обратно - PullRequest
2 голосов
/ 19 июня 2019

Пожалуйста, не спрашивайте, почему, но я должен хранить строку (максимум 4 символа) в целочисленном значении (4 байта).

Сначала я написал это, и оно работает:

String value = "AAA";
int sum = IntStream.range(0, value.length())
                   .limit(4)
                   .map(i -> value.charAt(i) << (i * 8))
                   .sum();

System.out.println(sum);

Я не мог придумать функциональное решение для обратного пути.

StringBuffer out = new StringBuffer();
while (sum > 0) {
    int ch = sum & 0xff;
    sum >>= 8;
    out.append((char) ch);
}

Есть идеи написать обратный путь (к "ААА") функционально?

Ответы [ 6 ]

3 голосов
/ 19 июня 2019

Возможно, это не лучший способ преобразовать его обратно в String с использованием потоков;Ваш существующий цикл while выглядит чище и может быть более производительным.Однако существует потоковое решение.

String result = IntStream.range(0, 4)
        .map(i -> (value >>> 24 - (i * 8)) & 0xFF)
        .dropWhile(i -> i == 0)
        .mapToObj(v -> String.valueOf( (char) v))
        .collect(Collectors.joining());

Это генерирует некоторые байтовые индексы, принимает определенное значение байта, отображает его в char, а затем соединяет их обратно в String.Он также отбрасывает первые 0 значений, используя Java 9+ метод dropWhile.

Я исправил это, чтобы получить правильный порядок, добавив «24 -», чтобы получить наиболее значимыйпервый байт.

При value, равном 0x10101 * 65, возвращается "AAA"value из 0x10101 * 65 + 1 это возвращает "AAB".

3 голосов
/ 19 июня 2019

Одним из решений может быть:

StringBuilder out =
    IntStream.iterate(sum, s -> s > 0, s -> s >> 8)
             .mapToObj(s -> (char) (s & 0xff))
             .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);

System.out.println(out.toString());

Примечание. Я использовал перегрузку с тремя аргументами IntStream.iterate, доступную начиная с Java 9.

2 голосов
/ 19 июня 2019

это в основном char [4], который передается в int, а затем обратно.Реально я бы предположил, что это будет работать

public static String getStr(int encoded){
    return ((char)(encoded >> 24) + ((char)((encoded >> 16) 0xFF)
            + ((char)((encoded >> 8) & 0xFF) + ((char)((encoded) & 0xFF)
}
1 голос
/ 19 июня 2019
  • Создана строка значений сдвига для суммирования.
  • Маска для каждого символа.
  • Преобразование в строку.
  • И соединение сколлектор.
   String str = IntStream.of(0, 8, 16, 24)
            .mapToObj(i->(char)(sum>>i&0xff)+"")
             .collect(Collectors.joining());
1 голос
/ 19 июня 2019

Спасибо всем за ваш вклад. Я нашел другое решение, чтобы поделиться с вами:

String str = IntStream.iterate(sum, s -> s >> 8)
                      .limit(4)
                      .filter(s -> s > 0)
                      .mapToObj(s -> String.valueOf((char) (s & 0xff)))
                      .collect(Collectors.joining());
1 голос
/ 19 июня 2019

Это очень похоже на ваше, но, возможно, будет полезно

    String str = IntStream.iterate(sum, s -> s > 0, s -> s >> 8)
            .mapToObj(s -> String.valueOf((char)(s & 0xff)))
            .collect(Collectors.joining());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...