Start learning free

LESSON 260 OF 671 · RECORDS, SORTING & BUILT-INS

Tuples in Java: Records for Grouped Values

Lesson Read the full explanation

TL ; DR:

A record is a tiny class that only holds values, like a movie's title and year. One line declares it. You read each value by its name.


record Movie(String title, int year) {}   // outside Solution

Movie film = new Movie("Frozen", 2013);

System.out.println(film.title());         // Frozen

System.out.println(film.year());          // 2013

System.out.println(film);                 // Movie[title=Frozen, year=2013]


Full lesson:

Some values belong together. A movie has a title and a year. A point has an x and a y. Java keeps values like these in a record.

  • record Movie(String title, int year) {} declares a record. Its values go in the parentheses, each with its type.
  • A record is a class, so it goes outside Solution. Java writes its constructor and methods for you.
  • new Movie("Frozen", 2013) makes one. The values go in the declared order.
  • film.title() reads the title, and film.year() the year. Don't forget the parentheses.

Java can't unpack a record in one line. Copy each value you need into a variable, like String title = film.title().

A method can return only one value. To return two, it returns a record that holds both.

A record can't be changed. Its values are fixed when it's made. To change one, make a new record, like new Movie("Frozen", 2014).

Printing a record shows all its values, like Movie[title=Frozen, year=2013].


Your task

Rex the dog went for a long walk. pet holds his name and his age.

First, declare a record Time that holds two ints, hours and mins.

Then make splitTime return a new Time: the whole hours and the minutes left.

Last, call splitTime(135). Keep its result in a Time named walk.

The code already prints the three lines.

Expected output:

Rex
Rex is 4
Rex walked 2 h 15 min
STEP 1 OF 3
    Ctrl + Enter to check

    JAVA · RECORDS, SORTING & BUILT-INS

    Tuples in Java, explained

    What a record is

    Some values belong together: a pet has a name and an age, a point has an x and a y. Java keeps values like these in a record, a small class whose only job is to hold them. One line declares it:

    record Pet(String name, int age) {}
    

    The values go in the parentheses, each with its type. The body {} is empty because Java writes the constructor and the reading methods for you. A record is a class, so it is declared outside Solution, not inside a method.

    Making and reading a record

    Make one with new, giving the values in the declared order. Read each value by its name, with parentheses, because the names are methods:

    Pet rex = new Pet("Rex", 4);
    System.out.println(rex.name());
    System.out.println(rex.age());
    System.out.println(rex);
    

    This prints:

    Rex
    4
    Pet[name=Rex, age=4]
    

    Printing the record shows all its values. Two records with the same values are equal: rex.equals(new Pet("Rex", 4)) is true.

    Gotchas

    • Parentheses are required. rex.age() reads the age. Writing rex.age is a compile error, age has private access in Pet, because the field itself is hidden.
    • A record can't be changed. Its values are fixed when it is made. To change one, make a new record: new Pet("Rex", 5) prints as Pet[name=Rex, age=5].
    • No one-line unpacking. Java can't split a record into variables in a single statement here. Copy each value you need: String name = rex.name();.

    Why a record and not two separate variables

    Two loose variables, String petName and int petAge, work until you have to pass a pet to a method, return one, or keep several in a list. Then the two values have to travel together by hand, and it is easy to mix up the name of one pet with the age of another. A record makes the pair one value with a type of its own, Pet, so a method can take a Pet and a list can hold Pet items. Printing such a list shows each record in full: [Pet[name=Luna, age=3], Pet[name=Coco, age=9], Pet[name=Milo, age=9]].

    Because the names belong to the record, the code that reads it says what each value means. pet.age() is clearer than the second item of an array.

    Returning two values

    A method can return only one value. To give back two, it returns a record that holds both. That is the idea behind the lesson's task: splitTime turns a number of minutes into hours and minutes left over.

    The lesson's task step by step

    1. Declare record Time(int hours, int mins) {} below the Pet record, outside Solution.
    2. In splitTime, return a new Time built from minutes / 60 (whole hours, because integer division drops the remainder) and minutes % 60 (the minutes left). For 135 that gives 2 and 15.
    3. Call splitTime(135) and keep the result in a Time named walk.

    The solution in Java

    record Pet(String name, int age) {}
    
    record Time(int hours, int mins) {}
    
    class Solution {
        public Time splitTime(int minutes) {
            return new Time(minutes / 60, minutes % 60);
        }
    
        public void mainFunction() {
            Pet pet = new Pet("Rex", 4);
            System.out.println(pet.name());
            System.out.println(pet.name() + " is " + pet.age());
    
            Time walk = splitTime(135);
            System.out.println(pet.name() + " walked " + walk.hours() + " h " + walk.mins() + " min");
        }
    }
    

    The output is:

    Rex
    Rex is 4
    Rex walked 2 h 15 min
    

    Other inputs behave as you would expect: splitTime(45) gives Time[hours=0, mins=45] and splitTime(60) gives Time[hours=1, mins=0].

    Key takeaways

    • A record groups values under names with one declaration.
    • Read values with name()-style calls; never change them, make a new record instead.
    • Return a record when a method has two answers.
    Keep going with Java500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free