web-dev-qa-db-fra.com

Pourquoi l'arbre de Java n'a-t-il pas de méthode get ()?

Que faire si je souhaite récupérer et mettre à jour des objets stockés dans un TreeSet?

La raison pour laquelle je pose la question est que je veux pouvoir conserver une structure de données qui stockera des étudiants ... Je veux que les données soient triées (par années - ce qui est une variable d'instance de Student) et - il faut être gardé en ordre même après avoir mis à jour une (ou plusieurs) note (s).

Ainsi, après avoir brièvement examiné les collections de Java, j'ai décidé de choisir TreeSet et de définir un comparateur comparant deux étudiants par leurs notes .. Le problème est que je viens de découvrir que TreeSet n'a pas de méthode get ()!

Toute aide ou suggestion serait grandement appréciée.

19
so.very.tired

Qu'attendriez-vous d'une méthode get() sur une Set?

  • Les ensembles ne sont pas indexés, donc une get(int index) n'a aucun sens. (Utilisez une List si vous voulez obtenir des éléments par index).
  • get(Object obj) n'aurait également aucun sens, car vous auriez l'objet que vous essayez déjà d'obtenir.
  • Il existe déjà une méthode contains() pour vérifier si une Set contient un objet.
  • Vous pouvez effectuer une itération sur une Set si vous voulez utiliser quelque chose avec tous les éléments de l'ensemble.
27
Jesper

Vous pouvez récupérer les éléments de l’arborescence à l’aide d’un Iterator. Vous pouvez essayer quelque chose comme ça:

Iterator<Integer> it = treeSet.iterator();

Integer current = 0;
while(it.hasNext() ) {
current = it.next();

}

J'espère que cela t'aides.

10
aryann

J'ai un cas où j'utilise deux TreeSets (car ils sont plus rapides dans les recherches). L'un de ces arbres est énorme et les objets dans les arbres sont différents. Je crée donc un objet fictif (de type 2, deuxième arbre) contenant les champs à trier, en utilisant les données d'un objet du petit arbre et vérifiant il y a une contrepartie sur le second. Maintenant, je dois vérifier une valeur de l'objet trouvé dans le deuxième arbre pour ajouter de la valeur à un rapport.

L'utilisation d'un itérateur, au lieu d'une recherche binaire pour récupérer l'objet dont j'ai besoin, annule le but d'utiliser un arbre binaire. La seconde arborescence mesure plus de 5 Go et recherche des correspondances avec les données de la première arborescence (200 Mo). J'ai besoin d'une stratégie de recherche qui ait du sens pour cette énorme quantité de données. J'ai donc choisi un arbre de recherche binaire. Les entrées sont uniques.

4
user259923

Généralement, vous ne voudrez pas récupérer un élément dans un ensemble lorsque vous l'avez déjà. Vous pouvez supprimer votre élément d'un ensemble ou savoir s'il appartient à un ensemble, c'est tout. Savoir ce que vous voulez faire, c'est indexer vos étudiants par classe, ainsi, l'indice est la note, pas l'objet lui-même. La carte est la solution.

Si j'étais vous, j'utiliserais la structure suivante, qui récupère rapidement tous les étudiants ayant le même grade (Ils sont également triés par grade):

private SortedMap<Integer,Set<Student>> _studentsByGrade = new TreeMap<Integer,Set<Student>>();

public void updateStudent(Student student, int oldGrade, int newGrade)
{
  getOrCreateContainer(oldGrade).remove(student);
  getOrCreateContainer(newGrade).add(student);
  student.setGrade(newGrade);
}

public Set<Student> getOrCreateContainer(int grade)
{
  Set<Student> set = _studentsByGrade.get(grade);
  if(set==null)
  {
    set = new HashSet<Student>();
    _studentsByGrade.put(grade, set);
  }
  return set;
}

N'oubliez pas de surcharger les égaux et le hashcode dans votre classe d'étudiant pour le faire fonctionner correctement.

Vous pouvez également vérifier la bibliothèque cqengine si vous souhaitez effectuer des indexations Java facilement et rapidement, mais la solution présentée ci-dessus convient parfaitement à votre utilisation.

3
David

Vous pouvez itérer l’arbre pour récupérer ses objets . Qu’en est-il de NavigableSet? il existe des méthodes pour la navigation à courte distance, comme 

E ceiling(E e) E floor(E e)
E higher(E e) E lower(E e)
1
CrisIf

TreeSet est trié lors de l'insertion. Si vous commandez par notes et que vous les modifiez après étant ajoutés, les éléments ne sont plus triés (même ordre que précédemment).

TreeSet n'utilise pas non plus equals() pour déterminer si un élément est déjà ajouté, mais utilise plutôt le comparateur (même ordre = même élément). Donc, si deux étudiants ont les mêmes notes, un seul d'entre eux est ajouté. De Javadoc

L’instance TreeSet effectue toutes les comparaisons d’éléments à l’aide de son compareTo (ou comparer) méthode, donc deux éléments qui sont considérés comme égaux par ceci méthode sont égaux, du point de vue de l'ensemble.

Au lieu d'utiliser TreeSet, vous pouvez utiliser un HashSet et trier les élèves par classe chaque fois que vous en avez besoin (créer une nouvelle liste contenant les étudiants, la trier et la parcourir par-dessus).

1
Peter Walser

S'il contient l'objet exact, le sol renvoie l'objet exact que vous recherchez.

if(set.contains(searchingObject)) {
   addonPartNumber =  p.floor(searchingObject);
}
1
Danish Kumar

Vous pouvez également utiliser for-each pour obtenir tous les éléments dans TreeSet.

TreeSet<String> words = new TreeSet<String>();
for(String w : words) {
    System.out.println(w);
}

Vous pouvez effectuer une itération pour copier les mots uniques de TreeSet dans des listes, ce qui vous donne le privilège d’utiliser get();.

J'espère que ça a aidé.

0
Srinu Babu Ruppa

C’est la réponse au problème que j’ai trouvé moi-même mais j’ai pensé qu’il devrait exister une get(elem) pour les ensembles, mais comme vous le savez, il n’existe pas .

Voici:

set.subSet(elem,true,elem,true).floor(elem);

Cela vous renvoie le premier objet égal à celui que vous recherchez.

REMARQUE: elem doit être égal à l'élément recherché et vous obtenez l'objet souhaitéOUet affectez un comparateur à l'ensemble qui les correspond sous la forme equals.


J'ai été surpris que personne ne l'ait inventé avant.

Thumbs up nécessaire: D

0
Alejandro Díaz