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.
Qu'attendriez-vous d'une méthode get()
sur une Set
?
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.contains()
pour vérifier si une Set
contient un objet.Set
si vous voulez utiliser quelque chose avec tous les éléments de l'ensemble.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.
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.
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.
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)
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).
S'il contient l'objet exact, le sol renvoie l'objet exact que vous recherchez.
if(set.contains(searchingObject)) {
addonPartNumber = p.floor(searchingObject);
}
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é.
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