Looking at a Java Class and its Methods Through a Kaleidoscope
Exploring the Java Stream
methods from multiple perspectives
Six Views of a Java Class
I have been exploring different ways of understanding the methods of large Java classes. I don’t mean large in terms of lines of code, but large in terms of number of methods. Feature-rich interfaces, sometimes referred to as humane interfaces, are not incredibly humane when you need to find a method, if you don’t know the name, or discover patterns and look for symmetry between types. Thankfully, we have computers to help us process large amounts of data very quickly. Class
and Method
declarations are an easily accessible treasure trove of information about libraries and applications that Java developers have at their fingertips. Unfortunately, beyond good old Javadoc we don’t have many ways to make them talk.
I’ve created some basic documentation tools for increasing my own understanding of the feature-rich API of Eclipse Collections. Of course, I use Eclipse Collections to help me understand Eclipse Collections. The tools I am creating allow me to understand any Java Class
and its Method
instances, not just Eclipse Collections classes. One might consider the tools I have been experimenting with as a kind of Javadoc++. I am writing this blog in the hopes it might confirm or deny the usefulness of some of these class/method views.
I’m also hoping this blog will bring more attention and interest to a user-defined method grouping feature that is missing in Java, that I learned from Smalltalk, and is known as Method Categories. Imagine being able to optionally tag each Method
in a Java Class
with something like methodCategory=”filtering”
or methodCategory=”transforming”
and then having JavaDoc, IDEs, and developers able to query this information through the Method
interface. I digress. Back to the views and groupings that I was able to create without any new Java features.
I have created five AsciiDoc generated views of a class and its methods to help me understand how the methods on the class are organized and if any interesting patterns exist. These views can help me understand class scope, naming patterns and any symmetry/asymmetry that might exist.
The six views of a Java class we will see in this blog are as follows:
- Javadoc
- Methods by First Letter
- Methods by Prefix
- Methods by Suffix
- Methods by Return Type
- Methods by Functional Interface Parameter Types
For views two through six, I used Eclipse Collections to group and count methods by different attributes based on the Class
and Method
types in Java.
There is no user-defined grouping mechanism for Java methods today, which would be the equivalent of method categories in Smalltalk. I used the available metadata about a Method
to build groupings of methods to create these additional views of methods using generated AsciiDoc. I hosted the generated AsciiDoc for the Java Stream
class in gists. I linked to the gists below and used GitHub’s ability to render AsciiDoc to have decent looking tables displayed inline.
Enjoy the following views of the Java Stream
class and its methods!
Six Views of Java Stream
We will explore the six views of a Java class using Java Stream as an example.
1. Javadoc
The first view of Stream
we can find online is the Javadoc for the class.
The Javadoc view shows us all the documentation about the class, and organizes a method summary with all methods listed in alphabetical order. While this may be suitable for some purposes, it does not help us find patterns in the methods, because there is only a flat view without any particular grouping. We can filter methods by static methods, instance methods, abstract methods, and default methods.
We can use the useful search widget in the top right corner to find things. There is also an interesting “Use” tab that can show us the places in the JDK where Java Stream
is used.
2. Stream Methods by First Letter
This is the simplest view of methods on a class. I use Eclipse Collections to group all of the methods of the Stream
class by their first letter, and sort them by the most frequent first letter to the least frequent.
In each letter, the methods are sorted alphabetically. The benefit of this view is the method compression. In the Javadoc view for Stream
, you have to scroll to see all of the methods. With this view, there is no scrolling on either my 27 inch monitor or laptop screen.
3. Stream Methods by Prefix
This view is slightly more interesting than grouping by first letter. Here we group the methods by any prefix they might have like “map” or “for”. The prefix is determined by the split between the initial lowercase letters in the method and the first uppercase letter. Methods with no prefix, or having all lowercase letters, show up in a category of “No Prefix”. This category shows up first because the table is sorted by the most frequent prefix to the least frequent prefix. Prefix does grouping/screen space compression and also serves as a rough approximation of categories for a majority of methods.
4. Stream Methods by Suffix
This view is an interesting variation on the grouping by prefix. Here we group the methods by any suffix they might have like “int” or “match”. The suffix is determined by the split between the last uppercase letter and the remaining lowercase letters in the method. Methods with no suffix, or having all lowercase letters, show up in a category of “No Suffix”. This category shows up first because the table is sorted by the most frequent suffix to the least frequent suffix.
5. Stream Methods by Return Type
In this view, which has methods grouped by their return types, we get to see a bit more information about each method. We can see the methods with their parameter types. This necessarily takes up a bit more screen real estate, but the extra information is potentially useful. The table is sorted by most frequent return type to least frequent return type. As we can see, Stream
is the most frequent return type from Stream
, which means there are a decent number of lazy methods on the Stream
interface. There are also four BaseStream
methods and nine primitive stream (IntStream
, LongStream
, DoubleStream
) methods which are also lazy.
6. Stream Methods by Functional Interface Parameter Types
This was the most complicated of the views to produce. In this view, we can see the methods, with their number of parameters as an emoji, grouped by each of the parameter types the methods take. The methods are filtered to only include parameter types that are Functional Interfaces (e.g. Predicate
, Function
, Consumer
). This view tells us which methods are lambda ready, and which Functional Interface has the most methods with it as a parameter type. The parameter number was included here, because as we can see on the BinaryOperator
row in the table, there are three overloaded versions of reduce
.
This view can quickly answer questions like “Where can I use a Predicate
with a Stream
?” or “Where can I use a Function
with a Stream
?”
Comparing Stream and RichIterable Lambda Enabled Methods
The sixth view of the Stream
interface methods allowed me to compare how lambda ready Stream
is compared to the RichIterable
interface from Eclipse Collections, based on the number of methods that accept the four most well known Functional Interfaces as parameters.
Consumer
is quoted in the above chart as the equivalent type in Eclipse Collections is named Procedure
.
If you feel like there are some useful methods missing in Stream
, you might be able to find them in RichIterable
. The detailed view of RichIterable
Methods by Functional Interface Parameter Types can be seen below.
Final Thoughts
Sometimes it’s helpful to build tools to help us augment our understanding of the Java classes and methods we use. Java gives us the capability to query Classes and Methods for a lot of useful information in code. Looking for everything in files can necessitate a lot of scrolling and testing of our memory. Information chunking is extremely helpful for humans. Grouping and Filtering are great options for aiding information chunking.
This is the first time I have used AsciiDoc in a gist included in a Medium blog. I was pleasantly surprised by the automatic rendering of the AsciiDoc tables by GitHub. Now that I know this is possible, I may use AsciiDoc tables in gists instead of screen captures for tables in the future.
I hope you found this blog and the five AsciiDoc generated Class
/Method
views of the Stream
class in Java useful. Please share this blog with others who you think may benefit from learning more about the method naming and organization on the Java Stream
class!
Enjoy!
I am the creator of and committer for the Eclipse Collections OSS project, which is managed at the Eclipse Foundation. Eclipse Collections is open for contributions.