Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

201
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda