问题
Please don't ask why but I have to store a string (max 4 char) in an integer value (so 4 bytes).
First I wrote this and it works:
String value = "AAA";
int sum = IntStream.range(0, value.length())
.limit(4)
.map(i -> value.charAt(i) << (i * 8))
.sum();
System.out.println(sum);
I was unable to think a functional solution for the way back.
StringBuffer out = new StringBuffer();
while (sum > 0) {
int ch = sum & 0xff;
sum >>= 8;
out.append((char) ch);
}
Any idea to write the way back (to "AAA") in a functional way?
回答1:
That's pretty similar to yours, but maybe will be helpful
String str = IntStream.iterate(sum, s -> s > 0, s -> s >> 8)
.mapToObj(s -> String.valueOf((char)(s & 0xff)))
.collect(Collectors.joining());
回答2:
It may not be the best way to convert it back to a String
using streams; your existing while
loop seems cleaner and may be more performant. However, there is a streams solution.
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());
This generates some byte indices, takes the specific byte value, maps it to a char
, them joins them back to a String
. It also drops leading 0 values using the Java 9+ method dropWhile.
I've corrected this to yield the proper order by adding the "24 -" to grab the most significant byte first.
With a value
of 0x10101 * 65
, this returns "AAA"
. With a value
of 0x10101 * 65 + 1
, this returns "AAB"
.
回答3:
One solution could be:
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());
Note: I used a three-argument IntStream.iterate overload that is available starting from Java 9.
回答4:
it's basically a char[4] that's being transferred to an int then back. Realistically I would imagine this would work
public static String getStr(int encoded){
return ((char)(encoded >> 24) + ((char)((encoded >> 16) 0xFF)
+ ((char)((encoded >> 8) & 0xFF) + ((char)((encoded) & 0xFF)
}
回答5:
Thanks to all for your contribution. I've found another solution to share with you:
String str = IntStream.iterate(sum, s -> s >> 8)
.limit(4)
.filter(s -> s > 0)
.mapToObj(s -> String.valueOf((char) (s & 0xff)))
.collect(Collectors.joining());
回答6:
- Created a string of shift values to go thru the sum.
- Mask off each character.
- Convert to a string.
- And join with a collector.
String str = IntStream.of(0, 8, 16, 24)
.mapToObj(i->(char)(sum>>i&0xff)+"")
.collect(Collectors.joining());
来源:https://stackoverflow.com/questions/56657840/java-fun-converting-a-string-4-chars-to-int-and-back