Java 21

code and collections

Java Software Engineer

Line of Business Public

Merlin Bögershausen / @mboegie

🌺🌺️ 🆚 🧟️🧟‍

🧩

String Concatenation

String invoiceTxt =
    "Hi " + name + ",\n"
  + "please send " + (value + tax) + "€ to us or we eat"
  + "your brain.\n\n"
  + "Sincerely\n"
  + "\tThe 🧟s";
  • hard to read ❌

  • hard to format ❌

  • need for braces ❌

String Builder

String invoiceTxt = new StringBuilder()
  .append("Hi ").append(name).append(",\n")
  .append("please send ").append(value + tax)
    .append("€ to us or we eat you brain.\n\n")
  .append("Sincerely\n")
  .append("\tThe 🧟s")
  .toString();
  • even worse to read ❌❌

  • hard to format ❌

  • very verbose ❌

String Format

String invoiceTxt = """
  Hi %s,
  please send %.2f€ to us or we eat you brain.

  Sincerely
    The 🧟s""".formatted(name, value + tax);
// pre Java 15
String.format("..", name, value + tax);
  • better to read ✅

  • easy to format ✅

  • decouple parameter from String ❌

What do we want?

maoam

What do we want?

  • Strings with runtime computed values

  • readable mix of expressions and Strings

  • easy Formatting of values

JEP 430 String Templates

String name = "Merlin";
int value = 34;
double tax = value * 0.1;

String invoiceTxt = STR."""
  Hi \{ name },
  please send \{ value + tax }€ to us or we eat you brain.

  Sincerely
    The 🧟s""";

With Format

// String name; int value; double tax;

String invoiceTxt = FMT."""
  Hi %s\{ name },
  please send %.2f\{ value + tax }€ to us or we eat you brain.

  Sincerely
    The 🧟s""";

Code Behind

@FunctionalInterface
public interface Processor<R, E extends Throwable> {

  // transform StringTemplate to Result
  R process(StringTemplate stringTemplate) throws E;

  // Factory Method for Processors
  static <T> Processor<T, RuntimeException>
    of(Function<? super StringTemplate, ? extends T> process){}
}

Code Behind

class Shuffler implements Processor<String, Throwable> {
  @Override
  public String process(StringTemplate st) throws Throwable {
    var values = st.values().reversed().iterator();
    var sb = new StringBuilder();
    st.fragments().reversed()
      .forEach(frag -> sb.append(frag).append(values.next()));
    return sb.toString();
  }
} // new Shuffler().""

var JSON = StringTemplate.Processor
  .of(st -> new JSONObject(st.interpolate()));

PoJo to String Full Circle

🛫 → 🛬

Needs

  • first and last letter

  • keep order and travers revers

  • add and remove at both ends

🤔List, (Sorted)Set, Deque 🧐

First’n’Last

// List
list.get(0); list.get(list.size() -1));
// Sorted Set at least
sortedSet.first(); sortedSet.last();
// Deque (double ended queue)
deque.getFirst(); deque.getLast();

👑Deque

Order’n’Reverse

// List
for(var it = l.listIterator(l.size()); it.hasPrevious();){ }
// sorted Set
sortedSet.descendingSet().forEach();
// Deque
for(var it = deque.descendingIterator(); it.hasNext();){ }

👑Sorted Set

Add’n’Remove

// List
l.add(0, "Hallo"); l.add("World");
// sorted Set
var tmp = new TreeSet<String>();
tmp.add("Hallo");
tmp.addAll(sortedSet);
tmp.add("World");
sortedSet = tmp;
// Deque
deque.addFirst("Hello"); deque.addLast("World");

👑Deque

And the winner is ⁉

The missing 🧩

SequencedCollectionDiagram20220216

Sequenced Collection

interface SequencedCollection<E> extends Collection<E> {
  // new method
  SequencedCollection<E> reversed();
  // methods promoted from Deque
  void addFirst(E); void addLast(E);
  E getFirst(); E getLast();
  E removeFirst(); E removeLast();
}

see SequencedCollection JavaDoc.

Sequenced Set

interface SequencedSet<E>
    extends Set<E>, SequencedCollection<E> {
  SequencedSet<E> reversed();    // covariant override
}

see SequencedSet JavaDoc.

Sequenced Map

interface SequencedMap<K,V> extends Map<K,V> {
  // new methods
  SequencedMap<K,V> reversed();
  SequencedSet<K> sequencedKeySet();
  SequencedCollection<V> sequencedValues();
  SequencedSet<Entry<K,V>> sequencedEntrySet();
  V putFirst(K, V); V putLast(K, V);
  // methods promoted from NavigableMap
  Entry<K, V> firstEntry(); Entry<K, V> lastEntry();
  Entry<K, V> pollFirstEntry(); Entry<K, V> pollLastEntry();
}

see SequencedMap JavaDoc.

Why now?

We live forward, but we understand backward.

— Søren Aabye Kierkegaard 1844

learn Java, it’s easy

Main

public class Main {
  public static void main(String[] args) {
    System.out.println("Hello 🧟‍-Land");
  }
}

Public Class with public static main with array parametern.

Flexible launching

Allow all non-private classes

  1. static void main(String[] args)

  2. static void main()

  3. void main(String[] args)

  4. void main()

Flexible launching

public class Main {
  public static void main(String[] args) {
    System.out.println("Hello 🧟‍-Land");
  }
}
class Main {
  void main() {
    System.out.println("Hello 🧟‍-Land");
  }
}

Grind the Gears!

Unnamed Class

SomeName.java

void main() {
  System.out.println("Hello 🧟-Land");
}

🚀 Launch 🚀

$ java SomeName.java
Hello 🧟-Land

And now as one

void main() {
    System.out.println("Goodbye Info Days")
}

Print invoice

int value = 34;
double tax = value * 0.1;
List<String> brainCarrier = //..

void main() {
  FMT."""
  Hi %s\{ brainCarrier.reversed().getFirst() },
  please send %.2f\{ value + tax }€ to us or we eat you brain.

  Sincerely
    The 🧟s""";
}

For all, Newbie or Hero

Contact

Me

MBoegie@fosstodon.org // @MBoegi // MBoegers

adesso

Infos // DevBlog

Approach direct

I'm here all day with cookies!

Jobs

qrcode adesso jobs

Image Credits