I. Principes Généraux▲
Java propose une bibliothèque d'interfaces et de classes relativement riche pour les collections d'objets.
La démarche de Java reste de proposer une interface et des implémentations standards..
De plus, et dans la logique d'un typage fort du langage, Java a introduit la notion de type générique déjà connue des développeurs C++. Ceci a pour objectif de contraindre le type des objets qu'une collection peut contenir.
Objective-C et Cocoa suivent un mode de fonctionnement opposé en limitant le typage fort et en ne proposant que des implémentations des principaux types de collections.
Cocoa ne propose pas de protocoles (interfaces) pour chaque type de collection. C'est en revanche une série compacte de classes qui est proposée. Moins riche probablement que dans les API Java, mais concentrée sur l'essentiel.
II. Types de tableaux▲
On peut distinguer deux catégories de types de tableaux :
- le type tableau proposé comme un type du langage. La déclaration et l'accès aux éléments utilise les crochets dans les deux cas.
- les classes "tableau" des bibliothèques de développement associées au langage.
Si le type tableau existe bien dans les deux langages, il n'est pas traité de la même façon. En Java le type est mis en œuvre par une classe interne de la machine virtuelle. Ce n'est pas le cas en Objective-C.
Le tableau se caractérise par un temps d'accès constant à chaque élément grâce à son organisation linéaire et un accès indexé.
Cocoa propose de différencier les tableaux qui peuvent être modifiés de ceux qui ne sont jamais modifiés. Ce modèle de conception est appliqué dans de nombreuses classes de Cocoa et permet de proposer des implémentations optimisées.
Il est ainsi possible pour une classe de retourner toujours la même instance si la valeur est identique.
Cocoa propose deux classes de tableaux :
- NSArray le tableau uniquement disponible en consultation.
- NSMutableArray le tableau dont le contenu peut être modifié.
Une troisième classe de tableaux est particulièrement dédiée au stockage de pointeurs vers de objets. NSPointerArray a la particularité de pouvoir contenir des références NULL.
Java propose pour sa part plusieurs classes comme :
- java.util.ArrayList<E> ;
- java.util.Vector<E>. Chacune de ces classes étant une implémentation de l'interface java.util.List<E>.
On peut remarquer que, contrairement à Java, Cocoa ne propose pas un protocole de base pour les différentes collections. Seul le protocole utilisé par l'itération est défini.
III. Création de tableaux▲
Comme en Java, Objective-C ne permet pas de construire un tableau à partir d'un variable de type tableau. Il existe cependant des solutions similaires.
Ainsi il est possible d'initialiser un tableau directement dans votre code avec un constructeur utilitaire arrayWithObjects :. Dans ce cas la liste des éléments doit être terminée par la valeur spécifique nil.
NSArray
*
tableSimple =
[NSArray
arrayWithObjects: @"Un"
,
@"tableau"
,
@"simple"
,
@"mais"
,
@"non"
,
@"modifiable"
,
nil
];
Attention : Un constructeur porte le même nom au pluriel près. Cette variante ne construit qu'un tableau d'un seul élément et n'accepte qu'un seul paramètre.
IV. Accès aux éléments▲
L'accès à un élément de tableau en Java suit le même modèle de conception que les JavaBeans :
- get(idx) pour obtenir un élément à la positon idx ;
- set(idx, objet) pour modifier l'élément à la positon idx.
Le principe est similaire en Cocoa :
- objectAtIndex : retourne l'objet stocké à l'index indiqué ;
- replaceObjectAtIndex:withObject : remplace l'objet stocké à l'index indiqué ;
- insertObject:atIndex : insère un objet à l'index indiqué ;
Exemple :
[tableModifiable objectAtIndex: 2
]
[tableModifiable replaceObjectAtIndex: 2
withObject
:
@"basique"
];
[tableModifiable insertObject: @"de chaines"
atIndex
:
3
];
Le nombre d'éléments du tableau est obtenu en accédant à la propriété count d'un NSArray. En Java, ce sera l'attribut length qui sera utilisé.
V. Itération sur les collections▲
Les deux langages proposent une syntaxe simplifiée pour parcourir l'ensemble des objets d'une collection. Chacune de ces syntaxe s'appuie sur des interface spécifiques qui doivent être implémentée par l'objet parcouru.
- Java : for ( Type Var : Collection ) { ... }
- Objective-C : for ( TypeVar in Expression ) { ... }
- Java : interface java.lang.Iterable<T>
- Objective-C : protocole NSFastEnumeration
Comme tout objet d'une classe qui implémente le protocole NSFastEnumeration, il est donc très simple de parcourir un tableau.
int
idx =
0
;
for
(
id
anItem in
tableSimple )
{
NSLog
(
@"Élément %d : %@"
, idx, anItem);
idx +=
1
;
}
L'équivalent Java serait :
int
idx =
0
;
for
(
String uneChaine : tableauNonModifiable )
{
System.out.println
(
"Elément "
+
idx+
" = '"
+
uneChaine+
"'"
);
idx +=
1
;
}
VI. Trier les données▲
Commençons par un rappel du principe de fonctionnement en Java :
- La classe Collections propose une méthode sort()
- Les éléments de la collection doivent simplement implémenter l'interface Comparable
Le fonctionnement en Cocoa n'est pas très éloigné et les différences mettent, une fois de plus, l'accent sur les différences philosophiques entre Java et Objective-C en mettant la priorité sur les sélecteurs plutôt que les protocoles :
- La classe NSMutableArray propose une méthode sortUsingSelector : ;
- Les éléments du tableau doivent proposer une méthode implémentant le sélecteur indiqué à la méthode de tri.
D'autres méthodes existent qui n'utilisent pas les sélecteurs :
- sortUsingComparator : a pour paramètre un bloc NSComparator
- sortUsingDescriptors :a pour paramètre un NSArray de NSSortDescriptor ;
- sortUsingFunction:Context : les paramètres sont alors une fonction C et un pointeur vers un objet contexte.
D'autres variantes existent également pour préciser des options particulières :
- sortWithOptions:usingComparator : ;
- sortWithSortDescriptors:recursively :
Je vous renvoie pour plus de détails aux références de ces sélecteurs pour les classes NSMutableArray et NSMatrix.
Remarque : Le tableau étant directement modifié, seules les collections mutable proposent cette fonctionnalité.
En pratique, pour trier un tableau de chaines de texte il suffit ainsi de quelques lignes :
SEL
selectCompareTexte =
@selector
(
localizedCaseInsensitiveCompare:);
[tableModifiable sortUsingSelector: selectCompareTexte];
Dans cet exemple nous utilisons le sélecteur localizedCaseInsensitiveCompare : qui est mis en œuvre dans NSString et permet de comparer deux chaines sans tenir compte de la casse (majuscules/minuscules) et en prenant en compte les spécificités linguistiques.
Rien de très différent d'une solution Java s'appuyant sur l'implémentation de Comparable dans String.
VII. Conclusion▲
Alors que les API de Java proposent un framework complet construit sur des interfaces fortement typées ; Objective-C et Cocoa se recentrent sur un minimum de classes. Une fois de plus ce sont les sélecteurs de méthodes qui sont à l'honneur pour les fonctionnalités.
Deux projets exemple, l'un en Java et l'autre en Cocoa, sont joints à cet article.
VIII. Documents joints▲
Exemple Java (Miroir) : Un projet NetBeans pour un exemple très simple d'utilisation des tableaux en Java.
Exemple Objective-C (Miroir) : Un projet XCode illustrant les principaux cas d'utilisation de NSArray.