Java streams 13. Create using BitSet.stream(), JarFile.stream(), or Pattern.splitAsStream()

In this post—the last one dedicated to stream creation—we will discuss the following three methods: 
IntStream BitSet.stream()
Stream<JarEntry> JarFile.stream()
Stream<String> Pattern.splitAsStream(java.lang.CharSequence)

We demonstrate the usage of each of these methods in the corresponding section below.

IntStream BitSet.stream()

The java.util.BitSet class stores each component of the bit set as a boolean value(0 for false, and 1 for true) in an array. Which means that the first bit has the index value 0, while other bits are indexed by positive integers. The size of the BitSet can grow/shrink in increments of 64 as needed. Here is an example:  

  
  BitSet bs = new BitSet();
  bs.set(63);
  System.out.println(bs.size());          //prints: 64
  System.out.println(bs.cardinality());   //prints: 1
  System.out.println(bs.length());        //prints: 64
  bs.set(64);
  System.out.println(bs.size());          //prints: 128
  System.out.println(bs.cardinality());   //prints: 2
  System.out.println(bs.length());        //prints: 65
  

As you can see, other properties of a BitSet are 
— cardinality—number of bits set to true;
— length—”logical size”, equal to the index of the highest set bit plus one.
We are not going to use them. They were demonstrated here just to give you an idea of what BitSet is.

The advantage of a BitSet is that it allows performing bitwise logical operations. For example, let us create a method that displays the content of the first 4 bits:

  
  private static void printFourBits(BitSet bs) {
      String b0 = bs.get(0) ? "1" : "0";
      String b1 = bs.get(1) ? "1" : "0";
      String b2 = bs.get(2) ? "1" : "0";
      String b3 = bs.get(3) ? "1" : "0";
      System.out.println(b0 + b1 + b2 + b3);
  }
  

We now use it to demonstrate the AND and OR bitwise operations on two BitSet objects. The result of each operation is stored in the first operand. If the second operand has more bits than the first one, those extra bits are ignored. Here is the demo code:

  
  BitSet bs1 = new BitSet();
  bs1.set(1);
  bs1.set(3);
  printFourBits(bs1);       //prints: 0101

  BitSet bs2 = new BitSet();
  bs2.set(3);
  printFourBits(bs2);       //prints: 0001

  bs1.and(bs2);  //bitwise AND
  printFourBits(bs1);       //prints: 0001

  bs1 = new BitSet();
  bs1.set(1);
  bs1.set(3);
  printFourBits(bs1);       //prints: 0101

  bs2 = new BitSet();
  bs2.set(3);
  printFourBits(bs2);       //prints: 0001

  bs1.or(bs2);  //bitwise OR
  printFourBits(bs1);       //prints: 0101
  

Now let us generate a stream from a BitSet object:

  
  BitSet bs = new BitSet();
  bs.set(9);
  bs.set(3);
  bs.set(9);
  bs.set(7);
  System.out.println(bs);                 //prints: {3, 7, 9}
  bs.stream().forEach(System.out::print); //prints: 379
     

Please, note how setting the number twice does not change the BitSet content. That is because the second setting sets to true the same bit in the BitSet. Also, observe that the stream of the values is always ordered because it receives values in ascending order from the lowest index to the higher ones.

Stream<JarEntry> JarFile.stream()

The JarFile class reads the content of a .jar file. The stream based on the JarFile objects emits an ordered sequence the .jar file entries. For example, we created project javablog-1.0.jar file (using command “mvn clean package”), copied it from the “target” directory into the “resources” folder, and were able to stream its content as follows:

  
  Path path = Path.of("src", "main", "resources", "javablog-1.0.jar");
  File file = new File(path.toString());
  try (JarFile jf = new JarFile(file)){
      jf.stream().forEach(System.out::println);
  } catch (Exception e) {
      e.printStackTrace();
  }
  

As you can see, we used try-with-resources construct to close the opened file and to catch all the exceptions. The result is as follows (we show only first few lines of the output):

  
  META-INF/
  META-INF/MANIFEST.MF
  files/
  files/level1/
  files/level1/level2/
  com/
  com/nick/
  com/nick/blog/
  com/nick/blog/streams/
  com/nick/blog/streams/standard/
  ...
  

For a .jar file with multiple releases support, one can use the versionedStream() method which returns a stream that emits the latest versioned entry associated with the corresponding base entry name. 

Stream<String> Pattern.splitAsStream(java.lang.CharSequence)

The splitAsStream() method takes as an input a string and splits it into subsequences. The subsequences separators are described by the regular expression used to create the Pattern object. For example:

  
  Pattern pattern = Pattern.compile("[\\,\\.\\-]");

  pattern.splitAsStream("one-two,three.four")
         .forEach(System.out::println);
  

As you can see, we have used a regular expression that describes a separator the symbols dot, comma, and dash. The result of the above code is as follows:

Any subsequence can be described in the regular expression and thus used as a separator.

This concludes the series of posts about stream creation.

In the next post, we will talk about stream operations.

See other posts on Java 8 streams and posts on other topics.
You can also use navigation pages for Java stream related blogs:
— Java 8 streams blog titles
— Create stream
— Stream operations
— Stream operation collect()
The source code of all the code examples is here in GitHub

, ,

Send your comments using the link Contact or in response to my newsletter.
If you do not receive the newsletter, subscribe via link Subscribe under Contact.

Powered by WordPress. Designed by Woo Themes