Why importing java.util.* is not enough to import stream?

Viewed 1933

Short Version:

I understand that it's a bad practice to import * and it's best to import what exactly we need explicitly. However, I'm curious why importing util.* does not include util.stream.*.

Long Version:

If I import java.util.stream.*;

this piece of code works successfully:

int[] a = {3, 4, 1};
ArrayList<Integer> list = Arrays.stream(a)
                          .boxed()
                          .collect(Collectors.toCollection(ArrayList::new));

However, if I remove the stream from the import:

import java.util.*;

It fails:

Main.java:20: error: cannot find symbol
                                .collect(Collectors.toCollection(ArrayList::new));
                                         ^
  symbol:   variable Collectors
  location: class Ideone
1 error

I have tried with Java 8 (1.8.0_201):

https://www.onlinegdb.com/online_java_compiler

Java 11 (11.0.11+9-Ubuntu-0ubuntu2.20.04):

https://www.programiz.com/java-programming/online-compiler/

and Java 12 (12.0.1+12):

https://ideone.com/7XfIFY

2 Answers

You are using wildcard import that imports all the classes inside the package not the sub-packages inside it.

import java.util.*;

The above import statement will import all the Classes inside the java.util package not the sub-package i.e java.util.stream ,So in order to import it, you need to have import statement like

import java.util.*;
import java.util.stream.*;

Read more on Importing packages

Although the package name looks more like a manifestation of a hierarchical relationship, but they are not.

The package name is most like a prefix for the class.

For specific instructions, please refer to the official document(Apparent Hierarchies of Packages)

Related