Saturday, April 08, 2023

kdb+/q - Converting a CSV String into a Table

I often find myself wanting to create quick in-memory tables in q for testing purposes. The usual way to create a table is by specifying lists of column names and values, or flipping a dictionary, as shown below:

([] name:`Alice`Bob`Charles;age:20 30 40;city:`London`Paris`Athens)

// or, using a dictionary:

flip `name`age`city!(`Alice`Bob`Charles;20 30 40;`London`Paris`Athens)

As you can see, it's quite difficult to visualise the table being created using this approach. That's why I sometimes prefer to create a table from a multi-line CSV string instead, using the 0: operator, as shown below:

("SIS";enlist",") 0:

name    age city
Alice   20  London
Bob     30  Paris
Charles 40  Athens

Note that you can also load from a CSV file:

("SIS";enlist",") 0: `$"/path/to/file.csv"
Related post:
kdb+/q - Reading and Writing a CSV File

Sunday, April 02, 2023

Java 20: Record Patterns in For Loops

Previously, I wrote about "Record Patterns" introduced in Java 19, that allow you to "deconstruct" records and access their components directly.

In Java 20 (released a couple of weeks ago!), record patterns have been enhanced so that they can also be used in for loops.

Here is an example that uses a nested record pattern in a for loop to print out a list of records:

record Author(String firstName, String lastName) {}
record Book(String title, Author author, double price) {}

static void printBooks(List<Book> books) {
  for (Book(var title, Author(var firstName, var lastName), var price): books) {
    System.out.printf("%s by %s %s for %.2f\n", title, firstName, lastName, price);
Related post:
Java 19: Record Patterns

Friday, January 06, 2023 in 2022

Happy 2023, everyone!

I'd like to wish everyone a great start to an even greater new year!

In keeping with tradition, here's one last look back at in 2022.

During 2022, I posted 7 new entries on I am also thrilled that I have more readers from all over the world! Thanks for reading and especially for giving feedback.

Top 3 posts of 2022:

I'm going to be writing a lot more this year, so stay tuned for more great techie tips, tricks and hacks! :)

Related posts:

Tuesday, December 27, 2022

Java: Collecting a Stream into an Existing Collection

The following snippet shows how you can collect a stream into an existing collection using Collectors.toCollection:

stream.collect(Collectors.toCollection(() -> existingCollection));

You may also be interested in reading my previous post about collecting a stream into an unmodifiable collection.

Saturday, December 24, 2022

Java 19: Virtual Threads

Java 19 introduces Virtual Threads, which are lightweight threads designed to improve application throughput. This is a preview language feature so must be enabled using --enable-preview.

As you know, the JDK implements platform threads (java.lang.Thread) as thin wrappers around operating system (OS) threads. OS threads are expensive to create, and the number of threads is limited to the number of OS threads that the underlying hardware can support. A platform thread captures the OS thread for the code's entire lifetime.

On the other hand, a virtual thread is an instance of java.lang.Thread that is not tied to a particular OS thread and does not capture the OS thread for the code's entire lifetime. A virtual thread consumes an OS thread only while it performs calculations on the CPU. This means that several virtual threads can run their Java code on the same OS thread, effectively sharing it. When code running in a virtual thread calls a blocking I/O operation, the JVM performs a non-blocking OS call and automatically suspends the virtual thread until it can be resumed later.

Virtual threads help to improve the throughput of thread-per-request style server applications in particular because such applications consist of a great number of concurrent tasks that are not CPU bound and spend much of their time waiting.

Here is an example which creates 10,000 virtual threads; however, the JDK runs the code on perhaps only one OS thread. If we were using 10,000 platform threads (and thus 10,000 OS threads) instead, the program might crash, depending on the hardware available. Virtual threads are cheap and plentiful, and there is no need to pool them.

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
  IntStream.range(0, 10_000).forEach(i -> {
    executor.submit(() -> {
      return i;

The java.lang.Thread class has been updated with new methods to create virtual and platform threads, such as:

// create a new unstarted virtual thread named "foo".

// create and start a virtual thread