Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

198
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda