Slices

+++ title = ‘Slices’ date = 2024-09-19T18:57:33+08:00 draft = false +++

Slices are an important data type in Java, offering a more powerful interface to sequences than arrays.

Unlike arrays, slices (or Lists in Java) are typed only by the elements they contain (not the number of elements). An uninitialized List equals to null and has length 0.

import java.util.*;

public class SlicesExample {
    public static void main(String[] args) {
        List<String> s = null;
        System.out.println("uninit: " + s + " " + (s == null) + " " + (s != null && s.size() == 0));

        // To create an empty slice with non-zero length, use the ArrayList constructor.
        s = new ArrayList<>(Arrays.asList(new String[3]));
        System.out.println("emp: " + s + " len: " + s.size() + " cap: " + ((ArrayList<String>) s).size());

        // We can set and get just like with arrays.
        s.set(0, "a");
        s.set(1, "b");
        s.set(2, "c");
        System.out.println("set: " + s);
        System.out.println("get: " + s.get(2));
        System.out.println("len: " + s.size());

        // In addition to these basic operations, slices support several more that make them richer than arrays.
        s.add("d");
        s.addAll(Arrays.asList("e", "f"));
        System.out.println("apd: " + s);

        // Slices can also be copied.
        List<String> c = new ArrayList<>(s);
        System.out.println("cpy: " + c);

        // Slices support a “slice” operator with the syntax list.subList(low, high).
        List<String> l = s.subList(2, 5);
        System.out.println("sl1: " + l);

        // This slices up to (but excluding) s[5].
        l = s.subList(0, 5);
        System.out.println("sl2: " + l);

        // And this slices up from (and including) s[2].
        l = s.subList(2, s.size());
        System.out.println("sl3: " + l);

        // We can declare and initialize a variable for slice in a single line as well.
        List<String> t = Arrays.asList("g", "h", "i");
        System.out.println("dcl: " + t);

        // The Collections utility class contains a number of useful utility functions for slices.
        List<String> t2 = Arrays.asList("g", "h", "i");
        if (t.equals(t2)) {
            System.out.println("t == t2");
        }

        // Slices can be composed into multi-dimensional data structures. The length of the inner slices can vary, unlike with multi-dimensional arrays.
        List<List<Integer>> twoD = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            List<Integer> innerList = new ArrayList<>();
            for (int j = 0; j <= i; j++) {
                innerList.add(i + j);
            }
            twoD.add(innerList);
        }
        System.out.println("2d: " + twoD);
    }
}

To run the program, compile the code into a .class file and then use java to execute it.

$ javac SlicesExample.java
$ java SlicesExample
uninit: null true false
emp: [null, null, null] len: 3 cap: 3
set: [a, b, c]
get: c
len: 3
apd: [a, b, c, d, e, f]
cpy: [a, b, c, d, e, f]
sl1: [c, d, e]
sl2: [a, b, c, d, e]
sl3: [c, d, e, f]
dcl: [g, h, i]
t == t2
2d: [[0], [1, 2], [2, 3, 4]]

Note that while slices (or Lists) are different types than arrays, they are rendered similarly by System.out.println.

Check out the official Java documentation for more details on the design and implementation of Lists in Java.

Now that we’ve seen arrays and slices we’ll look at Java’s other key data structure: HashMap.