Comment puis-je trier cette liste de tableaux de la façon que je veux?
Ici est un simple programme de tri d'une liste de tableaux:
ArrayList<String> list = new ArrayList<String>();
list.add("1_Update");
list.add("11_Add");
list.add("12_Delete");
list.add("2_Create");
Collections.sort(list);
for (String str : list) {
System.out.println(str.toString());
}
J'attendais la sortie de ce programme:
1_Update
2_Create
11_Add
12_Delete
Mais quand je lance ce programme, je suis sortie comme:
11_Add
12_Delete
1_Update
2_Create
Pourquoi est-ce et comment puis-je obtenir la liste de tableaux de tri comme le montre le résultat attendu?
- oui, c'est de faire des comparaisons de chaînes de pas entier.
- Essayez de regarder jusqu'à "Ordre Naturel" de Comparaison sourcefrog.net/projects/natsort
- Parce que son centre de tri comme une Chaîne de caractères Table ASCII
- Les chiffres sont à moins de trait de soulignement, donc "11" est inférieur à "1_".
Vous devez vous connecter pour publier un commentaire.
Vous pourriez écrire un personnalisé comparateur:
Lorsque vous triez les données de ce type comme une chaîne de caractères, c'est de comparer les personnages eux-mêmes, y compris les chiffres. L'ensemble de la chaîne de caractères qui commence par "1", par exemple, vont finir ensemble. Si la commande se termine comme cela...
1
10
100
2
20
200
À aucun moment, ne le tri "réaliser" que vous êtes attribuer une signification à des sous-ensembles de la chaîne, telles que la longueur variable des numéros à l'avant de la chaîne. Lors du tri des numéros de chaînes, la marge intérieure à gauche avec des zéros autant que nécessaire pour couvrir le plus grand nombre peut aider, mais il ne résout pas vraiment le problème lorsque vous n'avez pas de contrôle sur les données, comme dans votre exemple. Dans ce cas, le tri serait...
001
002
010
020
100
200
Il est classé en tant que texte (par ordre alphabétique), non pas comme des chiffres. Pour contourner cela, vous pourriez mettre en œuvre une coutume comparateur comme suggéré dans la réponse nsayer.
Il est en train de faire une comparaison lexicographique. Il compare le premier caractère de chaque chaîne de tri. Il compare ensuite la deuxième chaîne de ceux avec le même personnage. Quand il compare le caractère '_' pour un certain nombre, c'est plus de valeur que n'importe quel nombre de caractères comme 8 > 7 > 9. Rappelez-vous qu'il est en train de faire une comparaison de caractères et non pas une comparaison numérique.
Il existe des moyens pour mettre en œuvre votre propre personnalisé de tri routage qui peut être mieux que de renommer vos noms de script.
Si renommer vos noms de script est une option, cela peut permettre à d'autres outils de script à utiliser. Un format peut être
En gardant vos deux premiers chiffres à deux personnages, la comparaison lexicographique fonctionne.
Les Collections.méthode sort() de docs dit:
Ce qui signifie pour les Chaînes que vous allez obtenir la liste dans l'ordre alphabétique. La Chaîne 11_assign_privileges.sql vient avant la chaîne 1_create_table.sql et 12_07_insert_static_data.sql vient avant 1_create_table.sql etc. De sorte que le programme fonctionne comme prévu.
Parce que les chaînes sont classées dans l'une alphabétique tri et le caractère de soulignement est après les caractères pour les nombres. Vous devez fournir un comparateur de mise en œuvre de "l'Ordre Naturel" pour parvenir à un résultat souhaité.
La chaîne de comparer l'algorithme de comparer chaque personnage à la fois.
1
trie avant de2
. Il n'est pas question qu'elle est suivie par un1
ou un2
.Donc
100
serait trier avant2
. Si vous ne souhaitez pas ce comportement, vous avez besoin de comparer un algorithme qui gère ce cas.Comme d'autres l'ont dit, les éléments sont triés par ordre alphabétique par défaut. La solution est de définir un béton de java.util.Comparateur de classe et de le passer comme deuxième argument de la méthode de tri. Votre comparateur aurez besoin d'analyser les principaux entiers de cordes et de les comparer.
De Collection.sort() de tri de manière arbitraire, vous pouvez utiliser
Puis il suffit de mettre en œuvre un Comparateur qui coupe la corde et trie d'abord basée sur le nombre et ensuite sur le reste ou si vous voulez faire le tri.
Tout le monde l'a déjà souligné que l'explication est que vos chaînes de tri des chaînes de caractères, et un certain nombre ont déjà demandé à votre attention à l'Ordre Naturel de la comparaison de chaînes. Je vais juste ajouter que c'est un excellent exercice pour écrire ce comparateur vous-même, et une excellente occasion de pratiquer développement piloté par les tests. Je l'ai utilisé pour démontrer TDD au Code de Camp; dias & code sont ici.
Vous pouvez ajouter l'interface IComparable et trier ensuite par une propriété spécifique. Si vous avez une des collections d'articles d'un magasin par exemple, peut-être que vous souhaitez trier par prix ou par catégorie, etc. Si vous souhaitez commander par nom ici est un exemple:
notez comment la liste de tableaux sont triés par le nom de la propriété de l'un des éléments. Si vous n'ajoutez pas la IComparable puis lorsque vous utilisez la méthode de tri, il lèvera une erreur.
Comme indiqué ci-dessus, vous cherchez un Comparateur de mise en œuvre qui met en œuvre un naturel de tri. Jeff Atwood a écrit un excellent post sur le tri naturel il y a quelques temps - c'est bien intéressant à lire.
Si vous êtes à la recherche pour une implémentation de Java que j'ai trouvé pour être utile:
http://www.davekoelle.com/alphanum.html