Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

200
Views
Constructor personalizado de registros Java

Tengo un registro de Java que toma en una lista

 public record Zoo(List<Animal> animals ) { public Zoo(Collection<Animal> animals) { this(new ArrayList<>(animals)); } ... }

Sin embargo, los animales no están ordenados y quiero crear un registro donde se ordenen los animales. ¿Es esto posible en el registro de Java?

En la clase simple de Java, podría haber

 public class Zoo { ... public Zoo(List<Animal> animals) { this.animals = animals.sort(someComparator); } }
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Puede hacer lo mismo que con su "clase simple de Java".

 public record Zoo(List<Animal> animals) { /* * The canonical constructor copies the 'animals' list so that both * constructors have consistent behavior (ie they both result in * the list being copied). Plus, since you want to sort the list, it's * a good idea to create a copy anyway to avoid side-effects. * * FIXME: When the non-canonical constructor is used, the 'animals' list * will be copied twice. If anyone can think of a way to avoid * this, please let me know. */ // explicit canonical constructor public Zoo(List<Animal> animals) { this.animals = new ArrayList<>(animals); this.animals.sort(/* comparator */) } // a non-canonical constructor; must delegate to canonical constructor public Zoo(Collection<Animal> animals) { this(new ArrayList<>(animals)); } }

El primer constructor es una declaración explícita del constructor canónico. De la documentación de java.lang.Record :

Una clase de registro tiene los siguientes miembros obligatorios: un constructor canónico , que debe proporcionar al menos tanto acceso como la clase de registro y cuyo descriptor es el mismo que el descriptor de registro; un campo final privado correspondiente a cada componente, cuyo nombre y tipo es el mismo que el del componente; un método de acceso público correspondiente a cada componente, cuyo nombre y tipo de devolución son los mismos que los del componente. Si no se declara explícitamente en el cuerpo del registro, se proporcionan implementaciones implícitas para estos miembros.

[...]

Las razones principales para proporcionar una declaración explícita para el constructor canónico o los métodos de acceso son para validar los argumentos del constructor, realizar copias defensivas en componentes mutables o normalizar grupos de componentes (como reducir un número racional a los términos más bajos).

Tenga en cuenta que todos los demás constructores eventualmente deben delegar al constructor canónico.

over 4 years ago · Santiago Trujillo Report

0

Para evitar los problemas con List vs. Collection, ¿por qué no simplemente definir el Zoo con Collection<Animal> en lugar de List<Animal> ?

 public record Zoo(Collection<Animal> animals) { public Zoo(Collection<Animal> animals) { Objects.requireNonNull(animals, "animals is null"); List<Animal> list = new ArrayList<>(animals); Collections.sort(list); this.animals = list; } }

Si hay un código de cliente que realmente necesita animals() para devolver una List en lugar de una Collection , puede agregar un acceso personalizado:

 public List<Animal> asList() { return (List<Animal>) animals; }

Esta conversión es segura ya que el constructor canónico nunca asignará ningún tipo a animals que no sea un ArrayList . Me quedé con ArrayList ya que estaba en su ejemplo original, pero los registros son inmutables de forma predeterminada, por lo que tener un miembro que sea mutable es algo cuestionable. Si no se necesita mutabilidad, puede reemplazar la última línea del constructor con

 this.animals = List.copyOf(list);

O incluso reemplazar las últimas tres líneas del constructor con

 this.animals = animals.stream().sorted().toList();
over 4 years ago · Santiago Trujillo Report

0

Podría intentar usar la API Stream:

 public record Zoo(List<Animal> animals ) { public Zoo(Collection<Animal> animals) { this(animals.stream().sorted(someComparator).collect(Collectors.toList())); } ... }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!