3

I have ip address string like "192.168.1.1". Is it possible to parse string using java 8 streams and get primitive byte array as a result. Currently i have code

Arrays.stream(address.split("\\."))
      .map(UnsignedBytes::parseUnsignedByte)
      .toArray(Byte[]::new);

where is UnsignedBytes is guava class which return byte, but this code return Byte[] not byte[]

Update: Yes, i read about why ByteStream class is absent. My question is about, is it possible to get byte array using java-8 streams, without overhead such as create intermediate list.

user140547
  • 7,750
  • 3
  • 28
  • 80
pe4enko
  • 354
  • 4
  • 14
  • The only way I could possibly conceive of doing that would be to write a custom collector. That could work, but it might be tricky. – Louis Wasserman Jul 03 '16 at 21:08
  • You might collect to a list and use guava's `Bytes.toArray` to get a primitive array. – Hank D Jul 03 '16 at 21:27
  • 3
    Possible duplicate of [In Java 8, is there a ByteStream class?](http://stackoverflow.com/questions/32459683/in-java-8-is-there-a-bytestream-class) – user140547 Jul 03 '16 at 21:27
  • see the final `collect` in this answer: http://stackoverflow.com/a/36613808/3487617 – Hank D Jul 03 '16 at 21:38
  • 1
    Frankly, this is an interesting intellectual effort, but this is the kind of situation where a plain old simple for loop is much simpler and readable. And you won't parallelize that stream, so it doesn't even have that advantage. – JB Nizet Jul 03 '16 at 21:53

2 Answers2

3

You could just use Java's InetAddress class.

 InetAddress i = InetAddress.getByName("192.168.1.1");
 byte[] bytes = i.getAddress();
Robert
  • 7,394
  • 40
  • 45
  • 64
  • 1
    I like this answer, but the javadoc says *The result is in network byte order: the highest order byte of the address is in `getAddress()[0]`*. I think you need to reverse the byte array to suit OP's need. – Bohemian Jul 03 '16 at 22:42
  • @Bohemian Not sure what order the OP wants. The code above has 192 in `bytes[0]`, 168 in `bytes[1]`, and so on. Which makes sense to me. – Robert Jul 04 '16 at 02:08
  • I must have been thinking bits (where 0 is the "last" bit). This is fine! – Bohemian Jul 04 '16 at 04:14
1

You can use Pattern.splitAsStream(CharSequence) use a ByteArrayOutputStream in a collector:

byte[] bytes = Pattern.compile("\\.")
        .splitAsStream(address)
        .mapToInt(Integer::parseInt)
        .collect(
                ByteArrayOutputStream::new,
                ByteArrayOutputStream::write,
                (baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size())
        )
        .toByteArray();

Collect code adapted from https://stackoverflow.com/a/32470838/3255152.

Community
  • 1
  • 1
mfulton26
  • 29,956
  • 6
  • 64
  • 88
  • 1
    I like this answer better because it fits in the theme of the question, and would be useful outside of just parsing IP addresses. – lscoughlin Aug 17 '18 at 14:58