My plan is to write as much as I can
A long-term commitment to myself.
I’m sitting here on January 19th, 2025 wondering what to write. I’m almost finished writing my first book. I wrote 48 blogs in 2024. Writing has again become a permanent part of my life. I can’t imagine a world where I wasn’t writing something. If you’ve been reading my blogs for the past seven plus years, thank you! I hope my writing has brought something positive and useful into your life.
Writing is therapy for me. It’s where I get to sort out my thoughts. I tend to meander when I speak, and it’s the same when I write. The difference between speaking and writing is the ability to edit. It’s wonderful to meander in writing sometimes. I go back and read what I wrote, and move stuff around or just hit the delete key. Sometimes I write a whole blog, read it, and then delete it. I don’t feel the need to persist every thought I have. Sometimes I am the only audience, and I don’t feel the need to keep a memory for myself.
So why did I say writing is “again” a permanent part of my life. I was a writer in high school and college. I wrote poetry and prose and submitted many literary works for consideration to my high school and college literary magazines. A few of the many things I submitted got published, and I’ve shared some of my old published poetry in blogs on Medium.
I used to write with pen and paper, because when I was in high school, we didn’t have online blogging platforms. I captured my poetry in a text file on an old Franklin Ace 1000 and printed a few copies on my Epson MX-80 for myself and some high school friends. Once I finished university in the early 1990s, I stopped writing for myself. I wrote lots of stuff for work, and that was all.
Then, in August, 2017, I started blogging here. Blogging is a trippy experience. The possibility that something I write here might have some random impact on a reader anywhere in the world is wild. I hope the experiences are mostly positive. Most of the time, I have no idea who has read something I wrote. Sometimes when I chat with someone, they tell me they enjoy reading my blogs. This makes me feel good in the moment. It’s always nice to hear positive things.
It took me a while to get comfortable writing about personal experiences publicly. I started doing that as a result of the pandemic. I have since gotten more comfortable alternating between tech writing and personal stories.
Sometimes my stories weave together tech, personal, and career stuff. My favorite blog in that category is “The Joy of Programming.” In the poetry department, “Playing in the Sand” will likely always be my favorite. My favorite tech blog is “Java Streams are great but it’s time for better Java Collections.” It’s almost been five years since I wrote this one. My favorite personal blog is also almost five years old. Credit the pandemic for helping me find my personal blogging voice. The blog title is “What I learned about COVID-19 from Acute Myeloid Leukemia.” My favorite tech blog series is “The missing Java data structures no one ever told you about.” You can’t say no one told you about them now.
I have favored regularity of writing over notability. Why? Not everything I write is going to be amazing and world changing, and I’m ok with that. I aim for stuff I write to be well written, and maybe a few blogs a year will be notable. The practice of writing helps me to write better. If I only tried to write notable stuff, I probably would never write anything. I write when I am motivated to write. I don’t worry about how notable it will be. I don’t see any reason to change this for my blogs. If something doesn’t meet my own gauge for good enough, then I delete it.
When it came to writing my first book, which is about Eclipse Collections, I wanted to avoid the blogs I had previously written about Eclipse Collections. It would have been straightforward and take much less time to just wire together a couple hundred blogs. I wanted to write something new and notable that I would find fun to read, and that developers who read it could walk away with some useful lessons about designing and using a feature-rich library in Java or any programming language. I have at least met my goal of writing something I find fun to read. I hope once it is published others will enjoy it as well.
If you read this far, congratulations! I decided if I was going to share some background about the book, I would also share an excerpt of something interesting from chapter one.
Here is a table comparing lambda-enabled methods available in Eclipse Collections types and equivalent types in the JDK.
Since you don’t have the book in your hands to help you with context, a lambda-enabled method is a method that accepts a Functional Interface as a parameter. A Functional Interface in Java is an interface with a single abstract method. A Functional Interface is a type that can be represented in a method call using a lambda expression. Thus, the term lambda-enabled is any method that can have an inlined lambda expression passed as a parameter. Some examples of lambda-enabled methods in Java are forEach
, sort
, removeIf
, filter
, map
, reduce
.
Here’s a quick example of a lambda used with the forEach
method:
List.of("One", "Two", "Three").forEach(each -> System.out.println(each));
The lambda in this code snippet is each -> System.out.println(each)
and is the implementation of a Functional Interface named Consumer
.
I hope you enjoyed the book excerpt. If you’re wondering how I can count methods that can take lambdas as parameters, it’s simple enough to do in code. This is the code I used to create the table in the book.
private static final MutableList<String> FUNCTION_TYPES =
Lists.mutable.with(
"Function", "Predicate", "Consumer", "Procedure",
"Supplier", "Comparator", "Operator");
record ClassInfo(String className, int eagerMethods, int lazyMethods, int lambdaMethods)
{
public ClassInfo plus(ClassInfo other)
{
return new ClassInfo(
this.className,
this.eagerMethods + other.eagerMethods,
this.lazyMethods + other.lazyMethods,
this.lambdaMethods + other.lambdaMethods);
}
}
public static void viewJDKandECLambdaMethodCounts()
{
MutableList<Twin<Class<?>>> typePairs = Lists.mutable.with(
Tuples.twin(RichIterable.class, Iterable.class),
Tuples.twin(MutableCollection.class, Collection.class),
Tuples.twin(MutableList.class, List.class),
Tuples.twin(MutableSet.class, Set.class),
Tuples.twin(MutableStack.class, Stack.class),
Tuples.twin(MutableBag.class, Map.class),
Tuples.twin(MutableMap.class, Map.class),
Tuples.twin(MutableMultimap.class, Map.class),
Tuples.twin(MutableBiMap.class, Map.class),
Tuples.twin(LazyIterable.class, Stream.class),
Tuples.twin(LazyIntIterable.class, IntStream.class),
Tuples.twin(LazyLongIterable.class, LongStream.class),
Tuples.twin(LazyDoubleIterable.class, DoubleStream.class),
Tuples.twin(Collectors2.class, Collectors.class));
viewAsciiDocCombinedLambdaMethodCounts("Eclipse Collections", "JDK", typePairs);
}
public static void viewAsciiDocCombinedLambdaMethodCounts(
String left,
String right,
MutableList<Twin<Class<?>>> classes)
{
System.out.println(".Unlocking productivity gains with lambda-enabled methods");
System.out.println("[%autowidth.stretch]");
System.out.println("|===");
System.out.println("|" + left + " Type |Lambda Method Count |" + right + " Type |Lambda Method Count");
System.out.println();
ClassInfo totalJDK = new ClassInfo("*Total " + left + "*", 0, 0, 0);
ClassInfo totalEC = new ClassInfo("*Total " + right + "*", 0, 0, 0);
Twin<ClassInfo> totals = classes.injectInto(
Tuples.twin(totalJDK, totalEC),
ClassComparerAsciiDoc::outputCombinedLambdaMethodCountsForClasses);
outputLambdaClassInfos(totals.getOne(), totals.getTwo());
System.out.println("|===");
}
private static Twin<ClassInfo> outputCombinedLambdaMethodCountsForClasses(
Twin<ClassInfo> total,
Twin<Class<?>> clazz)
{
ClassInfo jdkClassInfo = getClassInfo(clazz.getOne());
ClassInfo ecClassInfo = getClassInfo(clazz.getTwo());
outputLambdaClassInfos(jdkClassInfo, ecClassInfo);
return Tuples.twin(total.getOne().plus(jdkClassInfo), total.getTwo().plus(ecClassInfo));
}
private static ClassInfo getClassInfo(Class<?> clazz)
{
ClassComparer returnComparer = new ClassComparer(true, true, false);
MutableSortedSet<String> methodNamesWithReturns =
returnComparer.getMethodNames(clazz);
MutableList<String> distinctMethods =
methodNamesWithReturns.toList().distinctBy(each -> each.split(":")[0]);
int eagerReturnMethods =
distinctMethods.count(
each -> LAZY_RETURN_TYPES.noneSatisfy(each.split(":")[1]::contains));
int lazyReturnMethods =
distinctMethods.count(
each -> LAZY_RETURN_TYPES.anySatisfy(each.split(":")[1]::contains));
int lambdaMethods = distinctMethods.count(
each -> FUNCTION_TYPES.anySatisfy(each.split(":")[0]::contains));
return new ClassInfo(clazz.getSimpleName(), eagerReturnMethods, lazyReturnMethods, lambdaMethods);
}
private static void outputLambdaClassInfos(ClassInfo jdkClassInfo, ClassInfo ecClassInfo)
{
System.out.println("|`" + jdkClassInfo.className() + "`");
System.out.println("|`" + jdkClassInfo.lambdaMethods() + "`");
System.out.println("|`" + ecClassInfo.className() + "`");
System.out.println("|`" + ecClassInfo.lambdaMethods() + "`");
System.out.println();
}
The work for getting info about a class is done by ClassComparer
, which is part of the Eclipse Collections eclipse-collections-testutils.jar
. I mentioned the ClassComparer
utility a while ago in this blog.
Anyway, that’s enough writing for today. Thanks for reading!
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.