IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

[COLLECTIONS] : LinkedHashSet : où sont les previous et next element ?


Sujet :

Langage Java

  1. #1
    Membre actif
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Points : 234
    Points
    234
    Par défaut [COLLECTIONS] : LinkedHashSet : où sont les previous et next element ?
    Bonjour,

    Habituellement je créé moi même ma structure de donnée chainée avec les liens sur les éléments suivant et précédent.

    Je découvre la classe LinkedHashSet et je me dit, cool c'est juste ce qu'il me faut. Mais je suis perplexe car je ne vois pas de fonction permettant d'accéder à l'élément suivant ou précédent. Il y a iterator vous me direz, oui mais ...... non ! C'est pas pareil ! Je veux pouvoir garder un élément d'une liste en mémoire par exemple, et reprendre facilement le parcours de la liste depuis cet élément. OK on peut le faire en gérant un itérateur etc ... Mais c'est lourd dingue à gérer : faut rester sur l'élément précédent pour utiliser le next() ... Quel dommage !

    ET SURTOUT, je ne vois aucun intérêt à LinkedHashSet par rapport à une HashSet simple .... ?

    Merci de m'éclairer si je suis passé à côté de quelque chose.
    Bonne journée.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    HashSet :

    Citation Envoyé par https://docs.oracle.com/javase/9/docs/api/java/util/HashSet.html
    It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
    LinkedHashSet :

    Citation Envoyé par https://docs.oracle.com/javase/9/docs/api/java/util/LinkedHashSet.html
    Hash table and linked list implementation of the Set interface, with predictable iteration order.

    [...]

    This implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet, without incurring the increased cost associated with TreeSet.
    Donc l'ordre d’itération est toujours le même dans LinkedHashSet mais il peut varier dans HashSet.
    Pour le reste ce sont des Set et si tu étais allé voir la doc de cette interface tu aurai vu que cette collection ne permet pas un accès direct a un de ses éléments, contrairement a la collection List.

    De plus, cette précision a été rajoutée sur les méthodes factories introduites dans le JDK9, il s'agit la du comportement par défaut des sets (hors classe spécialisée comme LinkedHashSet[/c]) qui ne sont pas ordonnes par nature :
    Citation Envoyé par https://docs.oracle.com/javase/9/docs/api/java/util/Set.html
    The iteration order of set elements is unspecified and is subject to change.
    Donc il te faut utiliser un itérateur (ou une liste qui a elle toujours un ordre de parcours identique).
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre actif
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Points : 234
    Points
    234
    Par défaut
    Bonjour Bouye,
    Merci pour ta réponse. J'ai bien vu ces explications dans la doc, et ce que je comprends, c'est que LinkedHashSet est ordonné avec des liens sur l'élément précédent et l'élément suivant. Mais désolé, ça ne répond pas à ma question qui est comment accéder à l'élément n-1 ou n+1 à partir de n.

    Je vois maintenant l'intérêt de la LinkedHashSet par rapport à HashSet qui est la garantie du parcours ordonné suivant l'ordre d'insertion.

    Dommage qu'il n'y ait pas les fonctions d'accès LinkedHashSet.next() et LinkedHashSet.previous() ! D'autant que tout est en place pour cela et que ses performances sont respectables.
    A noter que ces fonctions n'existent pas non plus dans LinkedList ...

    En postant ce sujet, je voulais m'assurer que je ne faisais pas d'impasse et que je ne passais pas à côté de quelque chose. Elle aura eu l'avantage de me fixer les idées sur ces collections et le choix que je faire dans mon contexte : je vais continuer à créer et gérer moi même mes listes chainées

    Encore merci Bouye.
    Je mets en résolu pour signaler qu'il n'y a pas de suite à donner.

    Cdt

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par kase74 Voir le message
    Dommage qu'il n'y ait pas les fonctions d'accès LinkedHashSet.next() et LinkedHashSet.previous() !
    Ce n'est pas faux que tout soit en place pour et je ne vois a priori rien qui rendrait ces accès contradictoires avec le reste du fonctionnement d'un LinkedHashSet.

    Mais j'ai aussi du mal à voir dans quel cas tu pourrais avoir besoin de faire ça et LinkedHashSet serait un meilleur choix qu'une List ou autre. Le mieux est encore de choisir la collection qui convient, et les fonctions nécessaires seront là (enfin si elles sont pas trop avancées quand même.)

    Citation Envoyé par kase74 Voir le message
    A noter que ces fonctions n'existent pas non plus dans LinkedList ...
    Ah, si. Il faut passer par un itérateur, c'est normal, mais elles sont là pour toutes les List.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Un Set ne permet pas l'accès direct à un élément précis sans passer par autre chose qu'un itérateur. Y a pas besoin de chercher midi à 14h, c'est ainsi et même pour ce cas spécial qu'est LinkedHashSet (et oui je suis d'accord ils auraient put tout aussi bien lui faire implémenter l'interface List que ça aurait rendu la vie des gens plus simple mais c'est comme ça).

    De manière générale tu vas le plus souvent écrire (en simplifiant) Set s = new LinkedHashSet() avec cette instance concrète créée bien loin en profondeur dans ton code (dans une fabrique ou un fournisseur de service). Donc tu manipuleras la super-interface Set, donc tu ne pourras pas accéder aux éléments que tu veux.

    Pour ce que tu demandes utilise List à la place. Et tu peux en créer une facilement à partir de ton set ou via les streams.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Membre actif
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Points : 234
    Points
    234
    Par défaut
    Bonjour,
    Merci à vous pour vos commentaires et recommandations. Je suis en train d'écrire une classe générique basée sur LinkedHashSet et intégrant des liens réels et leurs gestion.
    Je suis arrivé à terme de mon implémentation mais je ne retrouve pas les même performances que mes premiers tests avec une simple LinkedHasSet<Integer> !!! Bon , je vais investiguer ... Et dans le même temps je vais réétudier les list.

    Je mets le code de ma classe générique si ça intéresse ... Si vous avez des commentaires ou conseil n'hésitez pas, merci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    public class TrueLinkedHashSet<E> 
    {
    	public class TrueLinkedHashSetElement
    	{
    		private TrueLinkedHashSetElement _previousElem;
    		private E _data;
    		private TrueLinkedHashSetElement _nextElem;
     
    		@SuppressWarnings("unused")
    		private TrueLinkedHashSetElement()
    		{
    			// Nothing to do. Just to avoid empty instantiation
    		}
     
    		public TrueLinkedHashSetElement(E data)
    		{
    			super();
    			_data = data;
    		}
     
    		public final TrueLinkedHashSetElement getPreviousElem()
    		{
    			return _previousElem;
    		}
    //		public void setPreviousElem(TrueLinkedHashSetElement previousElem)
    //		{
    //			_previousElem = previousElem;
    //		}
    //		
    		public final E getData()
    		{
    			return _data;
    		}
    //		public void setData(E data)
    //		{
    //			_data = data;
    //		}
    //
    		public final TrueLinkedHashSetElement getNextElem()
    		{
    			return _nextElem;
    		}
    //		public void setNextElem(TrueLinkedHashSetElement nextElem)
    //		{
    //			_nextElem = nextElem;
    //		}
     
    		protected TrueLinkedHashSetElement clone()
    		{
    			return new TrueLinkedHashSetElement(_data);
    		}
     
    		@Override
    		public String toString()
    		{
    			return _data.toString();
    		}
     
     
    	}
     
    	private LinkedHashSet<TrueLinkedHashSetElement> _internalListOfElement;
    	private TrueLinkedHashSetElement _firstElem;
    	private TrueLinkedHashSetElement _lastElem;
     
    	public TrueLinkedHashSet()
    	{
    		_internalListOfElement = new  LinkedHashSet<TrueLinkedHashSetElement>();
    	}
     
    	public TrueLinkedHashSet(Collection<? extends TrueLinkedHashSetElement> c)
    	{
    		_internalListOfElement = new  LinkedHashSet<TrueLinkedHashSetElement>(c.size());
    		for(TrueLinkedHashSetElement elem : c)
    			_internalListOfElement.add(new TrueLinkedHashSetElement(elem._data));
    	}
    	public TrueLinkedHashSet(int initialCapacity)
    	{
    		_internalListOfElement = new  LinkedHashSet<TrueLinkedHashSetElement>(initialCapacity);
    	}
     
    	public boolean add(E e)
    	{
    		if(e==null)
    			return false; // Null element is not permitted
    		TrueLinkedHashSetElement newElem = new TrueLinkedHashSetElement(e);
    		if(_internalListOfElement.size()==0)
    		{
    			newElem._previousElem = null;
    			_firstElem = newElem;
    			_lastElem = newElem;
    		}
    		newElem._previousElem = _lastElem;
    		_lastElem._nextElem = newElem;
    		_lastElem = newElem;
     
    		return _internalListOfElement.add(newElem);
    	}
     
    	public void clear()
    	{
    		_firstElem = null;
    		_lastElem = null;
    		_internalListOfElement.clear();
    	}
     
    	public TrueLinkedHashSet<TrueLinkedHashSetElement> clone()
    	{
    		TrueLinkedHashSet<TrueLinkedHashSetElement> copy = new TrueLinkedHashSet<TrueLinkedHashSetElement>(_internalListOfElement.size());
    		for(TrueLinkedHashSetElement elem : _internalListOfElement)
    			copy.add(elem.clone());
    		return copy;
    	}
     
    	public boolean remove(E elemToRemove)
    	{
    		boolean result = false;
    		for(TrueLinkedHashSetElement elem : _internalListOfElement)
    		{
    			if(elem._data.equals(elemToRemove))
    			{
    				result = _internalListOfElement.remove(elem);
    				if(result)
    				{
    					elem._previousElem._nextElem = elem._nextElem;
    					elem._nextElem._previousElem = elem._previousElem;
    				}
    				return result;
    			}
    		}
    		return result;
    	}
     
    	public void addAll(Collection<? extends TrueLinkedHashSetElement> c)
    	{
    		if(c==null)
    			return;
    		for(TrueLinkedHashSetElement elem : c)
    			_internalListOfElement.add(new TrueLinkedHashSetElement(elem._data));
    	}
     
    	public TrueLinkedHashSetElement contains(E elemToSearch) throws Exception
    	{
    		if(elemToSearch==null)
    			throw new Exception(this.getClass().getName()+".contains(E elemToSearch) failed ! : elemToSearch can't be null !");
    		for(TrueLinkedHashSetElement elem : _internalListOfElement)
    			if(elem._data.equals(elemToSearch))
    				return elem;
    		return null;
    	}
     
    	@SuppressWarnings("unchecked")
    	public ArrayList<E>[] toArray()
    	{
    		return  (ArrayList<E>[]) _internalListOfElement.toArray(); // Warning is not significant here because the added object is necessarily of type <E>
    	}
     
    	public boolean isEmpty()
    	{
    		return _internalListOfElement.isEmpty();
    	}
     
    	public boolean hasNext(TrueLinkedHashSetElement elem) throws Exception
    	{
    		if(elem==null)
    			throw new Exception(this.getClass().getName()+".hasNext(TrueLinkedHashSetElement elem) failed ! : elem can't be null !");
    		return elem._nextElem!=null;
    	}
     
    	public TrueLinkedHashSetElement next(TrueLinkedHashSetElement elem) throws Exception
    	{
    		if(elem==null)
    			throw new Exception(this.getClass().getName()+".next(TrueLinkedHashSetElement elem) failed ! : elem can't be null !");
    		return elem._nextElem;
    	}
     
    	public int size()
    	{
    		return _internalListOfElement.size();
    	}
     
    	public String toString()
    	{
    		return _internalListOfElement.toString();
    	}
     
    	public final TrueLinkedHashSetElement getFirst()
    	{
    		return _firstElem;
    	}
     
    	public final TrueLinkedHashSetElement getLast()
    	{
    		return _lastElem;
    	}
    }

  7. #7
    Membre actif
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Points : 234
    Points
    234
    Par défaut
    J'ai réécrit mes classes en scindant l'élément de la LinkedHasSet (J'avais des warnings de transtypage non fiable).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    public class TrueLinkedHashSetElement<E>
    {
    	private TrueLinkedHashSetElement<E> _previousElem;
    	private E _data;
    	private TrueLinkedHashSetElement<E> _nextElem;
     
    	@SuppressWarnings("unused")
    	private TrueLinkedHashSetElement()
    	{
    		// Nothing to do. Just to avoid empty instantiation
    	}
     
    	public TrueLinkedHashSetElement(E data)
    	{
    		super();
    		_data = data;
    	}
     
    	public final TrueLinkedHashSetElement<E> getPreviousElem()
    	{
    		return _previousElem;
    	}
    	public void setPreviousElem(TrueLinkedHashSetElement<E> previousElem)
    	{
    		_previousElem = previousElem;
    	}
     
    	public final E getData()
    	{
    		return _data;
    	}
    	public void setData(E data)
    	{
    		_data = data;
    	}
     
    	public final TrueLinkedHashSetElement<E> getNextElem()
    	{
    		return _nextElem;
    	}
    	public void setNextElem(TrueLinkedHashSetElement<E> nextElem)
    	{
    		_nextElem = nextElem;
    	}
     
    	protected TrueLinkedHashSetElement<E> clone()
    	{
    		return new TrueLinkedHashSetElement<E>(_data);
    	}
     
    	@Override
    	public String toString()
    	{
    		return _data.toString();
    	}
     
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    public class TrueLinkedHashSet<E>
    {
     
    	private LinkedHashSet<TrueLinkedHashSetElement<E>> _internalListOfElement;
    	private TrueLinkedHashSetElement<E> _firstElem;
    	private TrueLinkedHashSetElement<E> _lastElem;
     
    	public TrueLinkedHashSet()
    	{
    		_internalListOfElement = new  LinkedHashSet<TrueLinkedHashSetElement<E>>();
    	}
     
    	public TrueLinkedHashSet(Collection<? extends TrueLinkedHashSetElement<E>> c)
    	{
    		_internalListOfElement = new  LinkedHashSet<TrueLinkedHashSetElement<E>>(c.size());
    		for(TrueLinkedHashSetElement<E> elem : c)
    			_internalListOfElement.add(new TrueLinkedHashSetElement<E>(elem.getData()));
    	}
    	public TrueLinkedHashSet(int initialCapacity)
    	{
    		_internalListOfElement = new  LinkedHashSet<TrueLinkedHashSetElement<E>>(initialCapacity);
    	}
     
    	public boolean add(E e)
    	{
    		if(e==null)
    			return false; // Null element is not permitted
    		TrueLinkedHashSetElement<E> newElem = new TrueLinkedHashSetElement<E>(e);
    		if(_internalListOfElement.size()==0)
    		{
    			newElem.setPreviousElem(null);
    			_firstElem = newElem;
    			_lastElem = newElem;
    		}
    		newElem.setPreviousElem(_lastElem);
    		_lastElem.setNextElem(newElem);
    		_lastElem = newElem;
     
    		return _internalListOfElement.add(newElem);
    	}
     
    	public void clear()
    	{
    		_firstElem = null;
    		_lastElem = null;
    		_internalListOfElement.clear();
    	}
     
    	public TrueLinkedHashSet<TrueLinkedHashSetElement<E>> clone()
    	{
    		TrueLinkedHashSet<TrueLinkedHashSetElement<E>> copy = new TrueLinkedHashSet<TrueLinkedHashSetElement<E>>(_internalListOfElement.size());
    		for(TrueLinkedHashSetElement<E> elem : _internalListOfElement)
    			copy.add(elem.clone());
    		return copy;
    	}
     
    	public boolean remove(E elemToRemove)
    	{
    		boolean result = false;
    		for(TrueLinkedHashSetElement<E> elem : _internalListOfElement)
    		{
    			if(elem.getData().equals(elemToRemove))
    			{
    				result = _internalListOfElement.remove(elem);
    				if(result)
    				{
    					elem.getPreviousElem().setNextElem(elem.getNextElem());
    					elem.getNextElem().setPreviousElem(elem.getPreviousElem());
    				}
    				return result;
    			}
    		}
    		return result;
    	}
     
    	public void addAll(Collection<? extends TrueLinkedHashSetElement<E>> c)
    	{
    		if(c==null)
    			return;
    		for(TrueLinkedHashSetElement<E> elem : c)
    			_internalListOfElement.add(new TrueLinkedHashSetElement<E>(elem.getData()));
    	}
     
    	public TrueLinkedHashSetElement<E> contains(E elemToSearch) throws Exception
    	{
    		if(elemToSearch==null)
    			throw new Exception(this.getClass().getName()+".contains(E elemToSearch) failed ! : elemToSearch can't be null !");
    		for(TrueLinkedHashSetElement<E> elem : _internalListOfElement)
    			if(elem.getData().equals(elemToSearch))
    				return elem;
    		return null;
    	}
     
    	@SuppressWarnings("unchecked")
    	public ArrayList<E>[] toArray()
    	{
    		return  (ArrayList<E>[]) _internalListOfElement.toArray(); // Warning is not significant here because the added object is necessarily of type <E>
    	}
     
    	public boolean isEmpty()
    	{
    		return _internalListOfElement.isEmpty();
    	}
     
    	public boolean hasNext(TrueLinkedHashSetElement<E> elem) throws Exception
    	{
    		if(elem==null)
    			throw new Exception(this.getClass().getName()+".hasNext(TrueLinkedHashSetElement elem) failed ! : elem can't be null !");
    		return elem.getNextElem() != null;
    	}
     
    	public TrueLinkedHashSetElement<E> next(TrueLinkedHashSetElement<E> elem) throws Exception
    	{
    		if(elem==null)
    			throw new Exception(this.getClass().getName()+".next(TrueLinkedHashSetElement elem) failed ! : elem can't be null !");
    		return elem.getNextElem();
    	}
     
    	public int size()
    	{
    		return _internalListOfElement.size();
    	}
     
    	public String toString()
    	{
    		return _internalListOfElement.toString();
    	}
     
    	public final TrueLinkedHashSetElement<E> getFirst()
    	{
    		return _firstElem;
    	}
     
    	public final TrueLinkedHashSetElement<E> getLast()
    	{
    		return _lastElem;
    	}
    }

  8. #8
    Membre actif
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Points : 234
    Points
    234
    Par défaut
    J'otiens des performances plus intéressantes :
    Temps moyen pour les add = 20075410 nano secondes = 0.020075410000000002s
    Temps moyen pour parcours complet et teste = 987372 nano secondes = 9.87372E-4s
    contre (avant)
    Temps moyen pour les add = 149517537 nano secondes = 0.149517537s
    Temps moyen pour parcours complet et teste = 31524265 nano secondes = 0.031524265s
    Voici mon process de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    		TrueLinkedHashSet<Integer> liste;
     
    		long cumulAdd = 0, cumulScan = 0;
    		int nbCmpt = 100;
    		for(int cmpt = 0;cmpt<nbCmpt;++cmpt) 
    		{
    			liste = new TrueLinkedHashSet<Integer>();
    			int i = 0;
    			long t1 = System.nanoTime();
    			for(;i<100000;++i)
    				liste.add(i);
    			long t2 = System.nanoTime();
    			cumulAdd+=t2-t1;
     
    			t1 = System.nanoTime();
    			TrueLinkedHashSetElement<Integer> elem = liste.getFirst();
    			while(liste.hasNext(elem))
    			{
    				int n = (int) elem.getData();
    				if(n==-1);
    				else;
    				elem = liste.next(elem);
    			}
    			t2 = System.nanoTime();
    			cumulScan+=t2-t1;
    		}
    		System.out.println("Temps moyen pour les add = "+(cumulAdd/nbCmpt)+" nano secondes = "+((cumulAdd/nbCmpt)*1E-9)+"s");
    		System.out.println("Temps moyen pour parcours complet et teste = "+(cumulScan/nbCmpt)+" nano secondes = "+((cumulScan/nbCmpt)*1E-9)+"s");
    Pour info avec une LinkedHasSet 'simple', j'avais comme résultats :
    Pour 10000 fois 100000 éléments LinkedHashSet<Integer> liste = new LinkedHashSet<Integer>();
    Temps moyen pour les add = 1208030 nano secondes = 0.0012080300000000001s
    Temps moyen pour parcours complet et teste = 627307 nano secondes = 6.27307E-4s
    Je pense, et c'est normal, que la généricité est gourmande à cause des transtypage. Mais le résultat est tout de même respectable je trouve.

    Je vais comparer avec une linkedList maintenant ...

  9. #9
    Membre actif
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Points : 234
    Points
    234
    Par défaut
    Dans le post précédent, j'ai corrigé une erreur dans ma boucle de test : je cumulais tous les add dans ma liste sans faire un clear de la liste. Après correction, voici les résultats pour les deux type HashSet et ArrayList :

    Pour 100 fois 100000 éléments TrueLinkedHashSet<Integer>
    Temps moyen pour les add = 20075410 nano secondes = 0.020075410000000002s
    Temps moyen pour parcours complet et teste = 987372 nano secondes = 9.87372E-4s
    Pour 100 fois 100000 éléments TrueLinkedArrayList<Integer>
    Temps moyen pour les add = 1555031 nano secondes = 0.0015550310000000001s
    Temps moyen pour parcours complet et teste = 629567 nano secondes = 6.29567E-4s
    On constate donc de meilleurs performances en ajout et parcours avec une arrayList comme base à ma classe.
    Ci-dessous le code définitif pour les éléments et la liste d'éléments :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    public class TrueLinkedCollectionElement<E>
    {
    	private TrueLinkedCollectionElement<E> _previousElem;
    	private E _data;
    	private TrueLinkedCollectionElement<E> _nextElem;
     
    	@SuppressWarnings("unused")
    	private TrueLinkedCollectionElement()
    	{
    		// Nothing to do. Just to avoid empty instantiation
    	}
     
    	public TrueLinkedCollectionElement(E data)
    	{
    		super();
    		_data = data;
    	}
     
    	public final TrueLinkedCollectionElement<E> getPreviousElem()
    	{
    		return _previousElem;
    	}
    	public void setPreviousElem(TrueLinkedCollectionElement<E> previousElem)
    	{
    		_previousElem = previousElem;
    	}
     
    	public final E getData()
    	{
    		return _data;
    	}
    	public void setData(E data)
    	{
    		_data = data;
    	}
     
    	public final TrueLinkedCollectionElement<E> getNextElem()
    	{
    		return _nextElem;
    	}
    	public void setNextElem(TrueLinkedCollectionElement<E> nextElem)
    	{
    		_nextElem = nextElem;
    	}
     
    	public final boolean hasNextElem()
    	{
    		return _nextElem!=null;
    	}
    	public final boolean hasPreviousElem()
    	{
    		return _previousElem!=null;
    	}
     
    	public TrueLinkedCollectionElement<E> clone()
    	{
    		return new TrueLinkedCollectionElement<E>(_data);
    	}
     
    	@Override
    	public String toString()
    	{
    		return _data.toString();
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    public class TrueLinkedArrayList<E>
    {
    	private TrueLinkedCollectionElement<E> _firstElem;
    	private ArrayList<TrueLinkedCollectionElement<E>> _internalListOfElement;
    	private TrueLinkedCollectionElement<E> _lastElem;
     
    	public TrueLinkedArrayList()
    	{
    		_internalListOfElement = new  ArrayList<TrueLinkedCollectionElement<E>>();
    	}
     
    	public TrueLinkedArrayList(Collection<? extends TrueLinkedCollectionElement<E>> c)
    	{
    		_internalListOfElement = new  ArrayList<TrueLinkedCollectionElement<E>>(c.size());
    		for(TrueLinkedCollectionElement<E> elem : c)
    			_internalListOfElement.add(new TrueLinkedCollectionElement<E>(elem.getData()));
    	}
    	public TrueLinkedArrayList(int initialCapacity)
    	{
    		_internalListOfElement = new  ArrayList<TrueLinkedCollectionElement<E>>(initialCapacity);
    	}
     
    	public boolean add(E e)
    	{
    		if(e==null)
    			return false; // Null element is not permitted
    		TrueLinkedCollectionElement<E> newElem = new TrueLinkedCollectionElement<E>(e);
    		if(_internalListOfElement.size()==0)
    		{
    			newElem.setPreviousElem(null);
    			_firstElem = newElem;
    			_lastElem = newElem;
    		}
    		newElem.setPreviousElem(_lastElem);
    		_lastElem.setNextElem(newElem);
    		_lastElem = newElem;
     
    		return _internalListOfElement.add(newElem);
    	}
     
    	public void clear()
    	{
    		_firstElem = null;
    		_lastElem = null;
    		_internalListOfElement.clear();
    	}
     
    	public TrueLinkedArrayList<TrueLinkedCollectionElement<E>> clone()
    	{
    		TrueLinkedArrayList<TrueLinkedCollectionElement<E>> copy = new TrueLinkedArrayList<TrueLinkedCollectionElement<E>>(_internalListOfElement.size());
    		for(TrueLinkedCollectionElement<E> elem : _internalListOfElement)
    			copy.add(elem.clone());
    		return copy;
    	}
     
    	public boolean remove(E elemToRemove)
    	{
    		boolean result = false;
    		for(TrueLinkedCollectionElement<E> elem : _internalListOfElement)
    		{
    			if(elem.getData().equals(elemToRemove))
    			{
    				result = _internalListOfElement.remove(elem);
    				if(result)
    				{
    					elem.getPreviousElem().setNextElem(elem.getNextElem());
    					elem.getNextElem().setPreviousElem(elem.getPreviousElem());
    				}
    				return result;
    			}
    		}
    		return result;
    	}
     
    	public void addAll(Collection<? extends TrueLinkedCollectionElement<E>> c)
    	{
    		if(c==null)
    			return;
    		for(TrueLinkedCollectionElement<E> elem : c)
    			_internalListOfElement.add(new TrueLinkedCollectionElement<E>(elem.getData()));
    	}
     
    	public TrueLinkedCollectionElement<E> contains(E elemToSearch) throws Exception
    	{
    		if(elemToSearch==null)
    			throw new Exception(this.getClass().getName()+".contains(E elemToSearch) failed ! : elemToSearch can't be null !");
    		for(TrueLinkedCollectionElement<E> elem : _internalListOfElement)
    			if(elem.getData().equals(elemToSearch))
    				return elem;
    		return null;
    	}
     
    	@SuppressWarnings("unchecked")
    	public ArrayList<E>[] toArray()
    	{
    		return  (ArrayList<E>[]) _internalListOfElement.toArray(); // Warning is not significant here because the added object is necessarily of type <E>
    	}
     
    	public boolean isEmpty()
    	{
    		return _internalListOfElement.isEmpty();
    	}
     
    	public boolean hasNext(TrueLinkedCollectionElement<E> elem) throws Exception
    	{
    		if(elem==null)
    			throw new Exception(this.getClass().getName()+".hasNext(TrueLinkedHashSetElement elem) failed ! : elem can't be null !");
    		return elem.getNextElem() != null;
    	}
     
    	public TrueLinkedCollectionElement<E> next(TrueLinkedCollectionElement<E> elem) throws Exception
    	{
    		if(elem==null)
    			throw new Exception(this.getClass().getName()+".next(TrueLinkedHashSetElement elem) failed ! : elem can't be null !");
    		return elem.getNextElem();
    	}
     
    	public int size()
    	{
    		return _internalListOfElement.size();
    	}
     
    	public String toString()
    	{
    		return _internalListOfElement.toString();
    	}
     
    	public final TrueLinkedCollectionElement<E> getFirst()
    	{
    		return _firstElem;
    	}
     
    	public final TrueLinkedCollectionElement<E> getLast()
    	{
    		return _lastElem;
    	}
    }

  10. #10
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Et pourquoi ne pas utiliser ListOrderedSet issu des collections Apache ?
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  11. #11
    Membre actif
    Inscrit en
    Juin 2002
    Messages
    409
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 409
    Points : 234
    Points
    234
    Par défaut
    Bonjour Bouye,
    Merci pour cette proposition. Je ne connaissais pas cette classe. Elle semble effectivement satisfaire mes besoins. Je n'ai pas les collections Apache installées par défaut (JV8), il faut certainement installé le plugin approprié. J'ai déjà avancé mon projet avec ma classe TrueLinkedArrayList et malheureusement je dois continuer et avancer mon travail sans perdre plus de temps. Dommage !! J'aime bien faire, comme ça, des petits breaks pour réfléchir et investiguer sur une solution, chercher de nouvelles fonctionnalités ... En tous cas je prends bonne note de cette info.
    Merci pour votre aide et vos conseils.
    Cdt.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Affcher les boutons "Previous" et "Next" (PHP/MySQL)
    Par Ludock dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 25/01/2015, 17h27
  2. Quels sont les meilleurs livres pour UML ?
    Par Matthieu Brucher dans le forum Livres
    Réponses: 33
    Dernier message: 31/01/2014, 10h36
  3. Réponses: 6
    Dernier message: 25/06/2010, 11h25
  4. [CR][Jetform] Quelles sont les différences ?
    Par littlecow dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 23/07/2002, 11h40
  5. quels sont les possibilitées???
    Par lolo-d dans le forum OpenGL
    Réponses: 11
    Dernier message: 16/05/2002, 00h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo