136 votes

Collections.emptyMap () vs nouveau HashMap ()

Quelles sont certaines des situations où je peux utiliser Collections.emptyMap() ? La documentation dit que je peux utiliser cette méthode si je veux que ma collection soit immuable.

Pourquoi voudrais-je une collection vide immuable? Dans quel but?

138voto

Sumit Singh Points 8601

De Efficace Java, Item #43 - "Return empty arrays or collections, not null" démontre retour d'un vide de la collection et peut-être même illustre l'utilisation de ces emptyList(), emptySet(), et emptyMap() méthodes sur les Collections de la classe pour obtenir un vide de la collection qui a également l'avantage supplémentaire d'être immuable. À Partir De L'Élément N ° 15 "Minimize Mutability".

À partir de Collections-emptySet-Collections-emptyList-Collections

Ses un type de langage de programmation. C'est pour les gens qui ne veulent pas les variables nulles. Donc, avant que le jeu est initialisé, ils peuvent utiliser l'ensemble vide.

private Set myset = Collections.emptySet();

void initSet() {
   myset = new HashSet();
}
void deleteSet() {
   myset = Collections.emptySet();
}

public boolean setExists()
{
  if(myset.equals(Collections.emptySet()))
  {
      return false;
  }
  else return true;
}

Ces méthodes offrent quelques avantages:

  1. Ils sont plus concis parce que vous n'avez pas besoin de taper explicitement le type générique de la collection, c'est généralement juste déduit du contexte de l'appel de méthode.

  2. Ils sont plus efficaces, car elles ne sont pas la peine de créer de nouveaux objets; ils viennent de ré-utiliser un vide existant et immuable de l'objet. Cet effet est généralement très mineur, mais il est parfois (bien que rarement) important.

32voto

Affe Points 24993

Il est, dans mon expérience personnelle, certes, très utile dans les cas où une API exige une collection de paramètres, mais vous n'avez rien à fournir. Par exemple, vous pouvez disposer d'une API qui ressemble à quelque chose comme ça, et ne pas autoriser les valeurs null références:

public ResultSet executeQuery(String query, Map<String, Object> queryParameters);

Si vous avez une requête qui ne prend aucun paramètre, il est certainement un peu du gaspillage de créer une table de hachage, ce qui implique l'attribution d'un tableau, où vous pouviez juste passer dans le Vide "Carte de" qui est en fait une constante, la façon dont il est mis en œuvre en java.util.Collections.

21voto

Marc O'Morain Points 1257

Pourquoi voudrais-je une immuable vide collection? Quel est le point?

Il existe deux types de concepts, ici, qui sont semblent étranges vus ensemble. Il fait plus de sens quand vous traiter de ces deux concepts séparément.

  • Tout d'abord, vous devez vous préférez utiliser un immuable collection plutôt qu'une mutable un dans la mesure du possible. Les avantages de immuablity sont bien documentés ailleurs.

  • Deuxièmement, vous devez vous préférez utiliser un regroupement vide plutôt que d'utiliser la valeur null comme une sentinelle. C'est bien décrit ici. Cela signifie que vous aurez beaucoup plus propre, plus facile à comprendre le code, avec de moins en moins de places pour les bugs à cacher.

Ainsi, lorsque vous disposez d'un code qui nécessite une carte, il est préférable de passer une carte vide plutôt que d'un nul pour indiquer l'absence d'une carte. Et la plupart du temps lorsque vous utilisez une carte, il est préférable d'utiliser un immuable de la carte. Donc, c'est pourquoi il n'y est une fonction de commodité pour rendre immuable de carte vide.

8voto

Roland Tepp Points 2647

Il y a quelques cas où vous préférez utiliser immuable cartes, listes, ensembles ou d'autres types de collections.

Premier et sans doute le plus important de cas d'utilisation est à chaque fois que vous revenez à la suite d'une requête ou d'un calcul qui retourne un ensemble (ou une liste ou sur la carte) de résultats, vous devriez préférer utiliser immuable des structures de données.

Dans ce cas, je préfère de beaucoup le retour immuable versions de ces comme cela reflète les faits de l'immuabilité d'un jeu de résultats d'un calcul beaucoup plus clairement, peu importe ce que vous faites avec les données plus tard, l'ensemble des résultats que vous avez reçus de votre requête ne devrait pas changer.

Deuxième commune de cas d'utilisation, c'est quand vous avez besoin de fournir un argument en tant que contribution à une méthode ou d'un service. Sauf si vous attendons à l'entrée de la collection d'être modifiées par le service ou méthode (qui est généralement une très mauvaise idée de conception), en passant dans une immuable de la collection au lieu de la mutable pourrait bien être l'raisonnable et sûre de choix dans de nombreux cas.

Je pense à elle comme "passage par valeur" de la convention.

Plus généralement - il est d'une pratique raisonnable d'utiliser un immuable structures de données lorsque les données croix de module ou de limites de service. Cela le rend beaucoup plus facile de raisonner sur les différences entre (immuable) d'entrée/sortie et mutable état interne.

Comme très bénéfique, cela aurait pour effet de l'accroissement de la sécurité et de la sécurité des threads de vos modules/services et assure le nettoyeur de la séparation des préoccupations.

Une autre bonne raison d'utiliser Collections.empty*() méthodes est leur manque notable de verbosité désirée. En pré-Java7 époque, si vous aviez une collection générique, vous avez eu à saupoudrer de type générique annotations de tous sur la place.

Il suffit de comparer ces deux déclarations:

Map<Foo, Comparable<? extends Bar>> fooBarMap = new HashMap<Foo, Comparable<? extends Bar>>();

contre:

Map<Foo, Comparable<? extends Bar>> fooBarMap = Collections.emptyMap();

Cette dernière a clairement gagne haut la main sur la lisibilité de deux manières:

  1. Dans la première déclaration, l'ensemble de l'instanciation d'une carte vide est enterré dans le bruit de type générique déclarations, faisant essentiellement trivial déclaration beaucoup plus énigmatique qu'il doit être.
  2. Outre l'absence notable de type générique annotation sur le côté droit, la deuxième version stipule clairement que la carte est initialisée à une carte vide. En outre, sachant que cette méthode retourne un immuable de la carte, il est maintenant plus facile pour moi de trouver où fooBarMap est attribué à un autre non vide juste valeur par la recherche d' /fooBarMap =/.

5voto

Jeff Bowman Points 9712

Pour un, vous pouvez vous en sortir avec la référence de partage. Un new HashMap() etc nécessitera un objet alloué, et peut-être quelques éléments supplémentaires pour stocker les données, mais vous avez seulement besoin d'une copie de immuable vide de collecte (list, set, map, ou de toute autre nature). Cela en fait un choix évident lorsqu'une méthode que vous appelez doit accepter une Carte, mais n'a pas besoin de le modifier.

Je suggère de vérifier Josh Bloch est Efficace Java, qui répertorie de très belles attributs des objets immuables (y compris la sécurité des threads).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X