[JAVA] Create a temporary class with new Object () {}

Introduction

Java's ʻObject class is a very important class in the superclass of all classes, but isn't it rare to newitself? In this article, I'll show you two code examples wherenew Object ()` makes sense.

Define a method inside a method

The following is a code example described in the comment "Implementing a combination of mathematics in Java --Qiita". A method that enumerates and returns k combinations from the string array data.

    static List<String[]> combination(String[] data, int k) {
        List<String[]> result = new ArrayList<String[]>();
        combination(data, 0, new String[k], 0, result);
        return result;
    }

    static void combination(String[] data, int di, String[] comb, int ci, List<String[]> result) {
        if (ci == comb.length) {
            result.add(comb.clone());
            return;
        }
        for ( ; di <= data.length - (comb.length - ci); di++) {
            comb[ci] = data[di];
            combination(data, di + 1, comb, ci + 1, result);
        }
    }

It consists of two methods, the one that is called directly from the outside is the two-argument combination, and the five-argument combination is used internally. The 5-argument combination is recalling itself, but of the 5 arguments, the 3 arguments (data, comb, result) specify exactly the same value as the argument. If Java can define methods nested, you shouldn't have to write the same arguments on the recall call. Unfortunately, you can't nest methods in Java. So let's rewrite it using new Object ().

    static List<String[]> combination(String[] data, int k) {
        int length = data.length;
        List<String[]> result = new ArrayList<String[]>();
        String[] comb = new String[k];
        new Object() {
            void combination(int di, int ci) {
                if (ci == k) {
                    result.add(comb.clone());
                    return;
                }
                for (; di <= length - (k - ci); di++) {
                    comb[ci] = data[di];
                    combination(di + 1, ci + 1);
                }
            }
        }.combination(0, 0);
        return result;
    }

The 5-argument combination is written insidenew Object () {}and the fixed 3 arguments (data, comb, result) are deleted. The new Object () {} in this code defines an anonymous inner class and at the same time creates an instance of that class. The .combination (0, 0) after the new Object () {} calls the combination (int di, int ci) defined in the inner class. The fixed 3 variables (data, comb, result) can be referenced from within the inner class, so there is no need to pass them as arguments for each call. I am creating a useless instance with new Object (), but the overhead is small because I only create one. Stack consumption is reduced because there are fewer arguments on the recall call.

Class for temporary data storage

Suppose you have a class like this:

public class Person {

    private final String name;
    private final String age;

    public Person(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return this.name;
    }

    public String getAge() {
        return this.age;
    }
}

Furthermore, suppose you have the following list of Persons.

List<Person> list = List.of(
    new Person("Yamada", "18"),
    new Person("Ichikawa", "72"),
    new Person("Sato", "39"),
    new Person("Tanaka", "9"));

Consider sorting this by ʻage in ascending order. Since ʻage is a string, it must be written like this to sort it as an integer.

    List<Person> result = list.stream()
        .sorted(Comparator.comparingInt(p -> Integer.parseInt(p.getAge())))
        .collect(Collectors.toList());

This works fine, but it's not very efficient because ʻInteger.parseInt (p.getAge ()) is executed twice each time the values are compared. Even with the fast sorting algorithm, ʻInteger.parseInt will be executed $ 2n \ log n $ times.

Map.Entry

Pairing an instance of Person with an integerized version of ʻagesolves this problem. In such cases, theMap.Entry` class is often used as a temporary storage location.

    List<Person> result = list.stream()
        .map(p -> Map.entry(Integer.parseInt(p.getAge()), p))
        .sorted(Comparator.comparingInt(Entry::getKey))
        .map(Entry::getValue)
        .collect(Collectors.toList());

The integer ʻageonly needs to be calculated once, but it is intuitively difficult to understand whereMap.Entry` is used.

Records Java 14 adds a feature called Records that makes it easy to define immutable classes for data storage. If you use this, it will be like this.

    record PersonWithAge(Person p, int age) {
        PersonWithAge(Person p) {
            this(p, Integer.parseInt(p.getAge()));
        }
    }

    List<Person> result = list.stream()
        .map(PersonWithAge::new)
        .sorted(Comparator.comparingInt(PersonWithAge::age))
        .map(PersonWithAge::p)
        .collect(Collectors.toList());

It's easier to understand, but it also feels a bit exaggerated because it defines a class for temporary storage.

new Object() This is what happens when you use new Object ().

    List<Person> result = list.stream()
        .map(p -> new Object() {
            int intAge = Integer.parseInt(p.getAge());
            Person person = p;
        })
        .sorted(Comparator.comparingInt(obj -> obj.intAge))
        .map(obj -> obj.person)
        .collect(Collectors.toList());

new Object () {...} is a temporary storage location that is only valid in this expression. Although it is an anonymous class, it is recognized in this expression as a full-fledged class with fields ʻintAgeandperson`.

Summary

How was that? You can see that the ʻObject` class also has various uses. I can't recommend it because it feels tricky, but I've been using it since I knew I could write it like this.

Recommended Posts

Create a temporary class with new Object () {}
[Rails6] Create a new app with Rails [Beginner]
[Rails 5] Create a new app with Rails [Beginner]
[Android] Inherit ImageView to create a new class
[Rails] rails new to create a database with PostgreSQL
Create a playground with Xcode 12
Mapping to a class with a value object in How to MyBatis
Create an immutable class with JAVA
Create a Vue3 environment with Docker!
Create a new app in Rails
Create exceptions with a fluid interface
Create a Maven project with a command
I can't create a Java class with a specific name in IntelliJ
Let's create an instance with .new yourself. .. ..
Create a jar file with the command
Create a simple web application with Dropwizard
[Rails withdrawal] Create a simple withdrawal function with rails
Create a MySQL environment with Docker from 0-> 1
[Memo] Create a CentOS 8 environment easily with Docker
Create a simple search app with Spring Boot
Create a CSR with extended information in Java
Create a simple bulletin board with Java + MySQL
[Windows] [IntelliJ] [Java] [Tomcat] Create a Tomcat9 environment with IntelliJ
Let's create a timed process with Java Timer! !!
[Rails] rails new to create a database with PostgreSQL
[Java] Create a collection with only one element
How to create a class that inherits class information
Create a team chat with Rails Action Cable
Create a SandBox account with fastlane spaces ip
Create a multi-key map with the standard library
[Java] Object class
Create a web api server with spring boot
Create a Spring Boot development environment with docker
Create an EC site with Rails 5 ⑨ ~ Create a cart function ~
How to delete a new_record object built with Rails
Create a widget template for iOS14 with Intent Configuration.
Create a Chat app with WebSocket (Tyrus) + libGDX + Kotlin
If there is a state transition, let's create a State class
Create a user with an empty password on CentOS7
[Machine learning] I tried Object Detection with Create ML [Object detection]
[Note] Create a java environment from scratch with docker
Create a Service with an empty model Liferay 7.0 / DXP
Create a simple demo site with Spring Security with Spring Boot 2.1
A memo that handles a class created independently with ArrayList
[Java] How to start a new line with StringBuilder
Try create with Trailblazer
[Java] Create a filter
A new employee tried to create an authentication / authorization function from scratch with Spring Security
Create a blog with Jekyll and GitHub Pages @ Theme setting
I tried to create a java8 development environment with Chocolatey
Tutorial to create a blog with Rails for beginners Part 1
Create a page control that can be used with RecyclerView
Create a Docker image with the Oracle JDK installed (yum
[Rails] I tried to create a mini app with FullCalendar
Create a Hello World web app with Spring framework + Jetty
Create a blog with Jekyll and GitHub Pages @ Initial Settings
Create a SlackBot with AWS lambda & API Gateway in Java
A series of steps to create portfolio deliverables with Rails
How to move another class with a button action of another class.
Until you create a Web application with Servlet / JSP (Part 1)
Tutorial to create a blog with Rails for beginners Part 2