Tales from the jar side: Java spliterators, Stream support, Biebl Ave Maria, Heaven Can Wait, and the usual social media silliness
Why did St Patrick drive the snakes out of Ireland? It was cheaper than flying. (rimshot)
Welcome, fellow jarheads, to Tales from the jar side, the Kousen IT newsletter, for the week of March 9 - 16, 2025. This week I taught Upgrade to Modern Java class as a full-day NFJS Virtual Workshop, and taught my regular courses at Trinity College (Hartford).
spliterator, FTW
Understanding comes in layers, like onions, or ogres.
Or parfait. Everybody likes parfait.
Whenever I learn something new, I’m painfully aware that I only know it at a surface layer, at least at first. Over time I hope I’ll be able to add depth. The real risk is that I’ll learn something incorrectly, and then teach it incorrectly during a training class. I hate when that happens. Fortunately that hasn’t happened for a while, at least as far as I know.
More likely I’ll encounter something that I think I should know, but I don’t, so I’ll try to “finesse” it during class. One of those examples in Java, is the concept of a spliterator.
When I teach functional Java, I talk about the categories of functional interfaces added in Java 8 in the java.util.function
package: Predicate
, Function
, Supplier
, and Consumer
. I tell the students how important those interfaces are, and how they’re used throughout the library, as well as in other libraries. Another capability added in Java 8 is that interfaces since then can have static and default methods. An example that combines both concepts is Iterator
, and interface that has been around since way back in Java 1.5, which now has a forEach
method that takes a Consumer
as an argument:
That’s a snapshot from the Javadocs for Iterator
. See the first method? That’s the one I want to show. The problem is the third method, marked with the keyword default
and called spliterator
.
During class I try to move past that method quickly, because I really don’t want anybody to ask me about it. I mean, I’ve only been coding in Java for about 30 years, and teaching functional features in Java for the last 10 (more or less since Java 8 was released), and I’ve written a book called Modern Java Recipes specifically about those features. There’s a real risk somebody might think I understood what the heck a spliterator was or when you might actually want to use one.
I know it stands for “splittable iterator,” but that doesn’t really clarify anything. Here’s the detailed documentation:
Yeah, clear as mud. I’ve tried to look at the documentation for the Spliterator
interface, but after saying it’s “an object for traversing and partitioning elements a source,” I get lost pretty quickly.
This week, as it happens, I finally ran into a spliterator that helped me understand the whole concept, at least at its shallowest level.
Recently, OpenAI released an updated API for web search. As usual, the Python library makes things easy, but if you want to use Java, you need to go to the REST endpoint:
Okay, that’s doable. But the output adds new elements, as they are wont to do:
Oh, good. The answer is in the content
element called text
, which isn’t too bad, but now there’s a whole new section of annotations
to deal with.
A year ago, when I was working on a book for this stuff, I took the attitude that the developer’s task now was to map both the input and the output JSON structures to Java records, then set up networking to transmit them, and parse the results. What’s frustrating is that every time the AI people modify the JSON structures, you have to update the records all over again. In the past couple of months I’ve learned that it’s easier to use a capability of the Jackson JSON library called JsonNode
, which lets you read the tree (using a method called, believe it or not, readTree
) and traverse it without doing all that mapping. This works well when you’re trying to get something to work quickly.
In this case, Jackson has a method on ObjectMapper
called readTree
(see? I told you) that takes the JSON content and returns a JsonNode
representing the root.
Here’s how you can extract the URLs:
Wait, what’s that spliterator
method doing in there? As it happens, Jackson is an old library, or at least it predates all those functional features added in Java 8. That means some of its methods return an Iterable
, rather than a Stream
. The StreamSupport
class in the Java standard library has a method called stream
that takes a Spliterator
and a boolean
as arguments and returns a Stream
.
In other words, the time to use a spliterator
is if you have an Iterable
and you want to convert it to a Stream
. It’s a one-liner that does the work for you. In this case, JsonNode
is an Iterable
(it implements the Iterable
interface), so you just call the spliterator
method on it, and add a boolean
that’s true
if you want a parallel stream and false
if you want a sequential one, and you go from there. In the code above, I convert to a Stream
, map it to the url
elements as text, filter out the empty ones, and return a List
of the result.
The bottom line is that I still don’t know what a Spliterator
is, not really, but I know that if I have an Iterable
and I want a Stream
, use the stream
method in StreamSupport
to convert from one to the other. That definitely goes in the “win” column.
Spring Data JPA
This reminds me that when I was working with Spring Data JPA, there’s an interface they provide called CrudRepository
, where “crud” stands for create, read (or retrieve), update, and delete — all the things you want a database to do with data. One of the methods in CrudRepository
is findAll
, which returns an Iterable
:
Iterable<T> findAll()
Returns all instances of the type.
I always found that method annoying, because I wanted a List
(which has a method called stream
I can use to convert it into a Stream
) rather than an Iterable
, which I didn’t know how to use other than in a loop. Now I understand all I had to do was to write
StreamSupport(repo.findAll().spliterator(), false) // returns a Stream
and I could go from there. Apparently I wasn’t the only person struggling, however, because in the latest version of Spring Data JPA, they now have an interface called ListCrudRepository
, whose only difference is that now findAll
returns a List
:
List<T> findAll()
Returns all instance of the type.
I suppose enough people complained that the library developers decided to add this method and avoid the whole issue.
I realize that’s a very long story to explain what is a pretty esoteric part of Java, but at least you’re better off than my friend Jonathan. I forced the poor guy to sit there, eyes glazing over, as I explained exactly how big a deal this was to me the next day at lunch. At least you can skip this whole section if you want.
By the way, the web search thing works, at least as well as any AI-driven web search works. I managed to add it as a tool to my LangChan4j demos, but I’ll save that for another time. I was going to make a video about that, but I’m a bit concerned that I’ll spend half the video explaining what I just learned about spliterators, and that wouldn’t be good for anybody.
My birthday
This week was my birthday. I therefore posted this:
In case that video doesn’t show for you, here’s the direct link:
That’s the seven-part acapella recording I made with YouTuber Jared Halley a couple years ago, which came out really well. He’s the real professional. He recorded all seven parts, so I could listen to them as I recorded the six parts I could handle. He then mixed everything and made the final video. I still like it, though.
You can find Jared at his YouTube channel, Jared Halley Music.
Heaven has waited long enough
One of my all-time favorite movies is Heaven Can Wait, starring Warren Beatty, Buck Henry, Julie Christie, James Mason, Charles Grodin, Dyan Cannon, and may other greats. It was released in 1978.
If you’ve never seen it, you have a real treat in front of you. The description from IMDB is simply:
A Los Angeles Rams quarterback, accidentally taken away from his body by an overanxious angel before he was meant to die, returns to life in the body of a recently murdered millionaire.
It’s a wonderful movie. I practically have it memorized. Here’s an out of context clip:
That shows how old the movie is. The owner asked for $67 million for the Los Angeles Rams, which supposedly were worth only $19 million at the time. Now the number probably would be around $2 billion or more.
Why am I bringing this up now? In the movie, Warren Beatty (as Joe Pendleton) shows up at the way station for his trip to heaven and insists he isn’t supposed to be there. They finally do a check on his arrival date.
That date, you probably guessed, is coming up soon. Here’s a snippet from the WikiPedia page:
Once in the afterlife, Joe refuses to believe that his time is up, and upon investigation, Mr. Jordan (the Escort's supervisor) discovers that Joe was going to just narrowly miss the truck and he was not destined to die until March 20, 2025, at 10:17 AM.
That’s four days from today. I’d like to have some kind of watch party for the movie. I’m trying to figure out how to do that. If I manage it, I’ll send out another newsletter this week and put something on my YouTube channel about it. Since March 20 is a Thursday, it might work better to wait for Friday night, or maybe the weekend. Let me know if you want to participate:
It’s truly an awesome movie. Let’s do this.
Toots and Skeets
Before I add these, I have a confession to make. It’s getting harder to find good posts, mostly because with the way the world is, I’m finding it increasingly difficult to browse social media at all. We’ll see how long this section lasts.
Elon, Suuuper Genius
My sense is, that’s not optimal. I’m sure Elon’s hard at work fixing that right away.
Speaking of Teslas
His prices are insane, just like he is.
Gee, I wonder
Those who don’t remember history
Relevant questions
I’m pretty sure I’ve heard that one before, but it’s still good. As I recall, the third question was, “Why is it in a bucket?”
Them’s fighting words
Blocked and reported.
The replies, however, are filled with people who loathed Forrest Gump, an opinion I respect.
Also, I’m convinced Dottie Hinson dropped that ball on purpose, and I’m still mad about it.
Hey, hey, we’re the monkees
Have a great week everybody.
Last week:
Upgrade to Modern Java, an NFJS virtual workshop
My regular Trinity College schedule
This week:
Week 1 of Spring in 3 Weeks, on the O’Reilly Learning Platform
JUnit 5 and AssertJ, ditto
Spring break week at Trinity :)
OK. What is a Spliterator?