J'ai ce code:
public static String SelectRandomFromTemplate(String template,int count) {
String[] split = template.split("|");
List<String> list=Arrays.asList(split);
Random r = new Random();
while( list.size() > count ) {
list.remove(r.nextInt(list.size()));
}
return StringUtils.join(list, ", ");
}
J'ai compris:
06-03 15:05:29.614: ERROR/AndroidRuntime(7737): java.lang.UnsupportedOperationException
06-03 15:05:29.614: ERROR/AndroidRuntime(7737): at java.util.AbstractList.remove(AbstractList.java:645)
Comment serait-ce la bonne façon? Java.15
Réponses:
Pas mal de problèmes avec votre code:
Au
Arrays.asList
retour d'une liste de taille fixeDepuis l'API:
Vous ne pouvez pas le
add
faire; vous ne pouvez pas enremove
sortir. Vous ne pouvez pas modifier structurellement leList
.Réparer
Créez un
LinkedList
, qui prend en charge plus rapidementremove
.Sur la
split
prise de regexDepuis l'API:
|
est un métacaractère regex; si vous voulez diviser sur un littéral|
, vous devez y échapper\|
, ce qui est un littéral de chaîne Java"\\|"
.Réparer:
Sur un meilleur algorithme
Au lieu d'appeler
remove
un à la fois avec des indices aléatoires, il est préférable de générer suffisamment de nombres aléatoires dans la plage, puis de parcourir laList
fois avec unlistIterator()
, en appelantremove()
aux indices appropriés. Il y a des questions sur stackoverflow sur la façon de générer des nombres aléatoires mais distincts dans une plage donnée.Avec cela, votre algorithme le serait
O(N)
.la source
Random
chaque fois. Faites-en unstatic
champ et semez-le une seule fois.Celui-ci m'a brûlé plusieurs fois.
Arrays.asList
crée une liste non modifiable. Du Javadoc: Renvoie une liste de taille fixe soutenue par le tableau spécifié.Créez une nouvelle liste avec le même contenu:
Cela créera un peu de déchets supplémentaires, mais vous pourrez les muter.
la source
Probablement parce que vous travaillez avec un wrapper non modifiable .
Modifiez cette ligne:
à cette ligne:
la source
unmodifiable
etimmutable
.unmodifiable
signifie exactement "modifiable, mais pas structurellement".unmodifiableList
wrapper et d'essayer unset
; ça jetteUnsupportedOperationException
. Je suis certain queCollections.unmodifiable*
cela signifie vraiment une immuabilité totale, pas seulement structurelle.Je pense que remplacer:
avec
résout le problème.
la source
La liste renvoyée par est
Arrays.asList()
peut-être immuable. Pourriez-vous essayerla source
Lisez simplement le JavaDoc pour la méthode asList:
Cela vient de Java 6, mais il semble que ce soit la même chose pour Android Java.
ÉDITER
Le type de la liste résultante est
Arrays.ArrayList
, qui est une classe privée dans Arrays.class. En pratique, ce n'est rien d'autre qu'une vue de liste sur le tableau avec lequel vous êtes passéArrays.asList
. Avec une conséquence: si vous modifiez le tableau, la liste est également modifiée. Et comme un tableau n'est pas redimensionnable, l'opération de suppression et d'ajout doit être non prise en charge.la source
Arrays.asList () renvoie une liste qui ne permet pas les opérations affectant sa taille (notez que ce n'est pas la même chose que "non modifiable").
Vous pouvez faire
new ArrayList<String>(Arrays.asList(split));
pour créer une copie réelle, mais en voyant ce que vous essayez de faire, voici une suggestion supplémentaire (vous avez unO(n^2)
algorithme juste en dessous).Vous souhaitez supprimer
list.size() - count
(appelons celak
) des éléments aléatoires de la liste. Il suffit de sélectionner autant d'éléments aléatoires et de les échanger auxk
positions finales de la liste, puis de supprimer toute la plage (par exemple, en utilisant subList () et clear () à ce sujet). Cela le transformerait en unO(n)
algorithme maigre et moyen (O(k)
est plus précis).Mise à jour : Comme indiqué ci-dessous, cet algorithme n'a de sens que si les éléments ne sont pas ordonnés, par exemple si la liste représente un sac. Si, en revanche, la Liste a un ordre significatif, cet algorithme ne le conserverait pas (l'algorithme des polygénubrifiants le ferait à la place).
Mise à jour 2 : Donc, rétrospectivement, un meilleur algorithme (linéaire, maintenant l'ordre, mais avec des nombres aléatoires O (n)) ressemblerait à ceci:
la source
ArrayList
. Beaucoup plus simple que ma suggestion. Je pense que cela entraînerait cependant une réorganisation des éléments.J'ai une autre solution à ce problème:
travailler sur
newList
;)la source
Cette exception UnsupportedOperationException survient lorsque vous essayez d'effectuer une opération sur une collection là où elle n'est pas autorisée et dans votre cas, lorsque vous l'appelez,
Arrays.asList
elle ne renvoie pas ajava.util.ArrayList
. Il renvoie unjava.util.Arrays$ArrayList
qui est une liste immuable. Vous ne pouvez pas y ajouter ni en supprimer.la source
Oui, le
Arrays.asList
retour d'une liste de taille fixe.Outre l'utilisation d'une liste chaînée, utilisez simplement
addAll
liste des méthodes.Exemple:
la source
Remplacer
à
ou
ou
ou (mieux pour supprimer des éléments)
la source
Arraylist narraylist = Arrays.asList (); // Retourne une liste immuable Pour la rendre mutable, la solution serait: Arraylist narraylist = new ArrayList (Arrays.asList ());
la source
Voici un extrait de code provenant de tableaux
donc ce qui se passe est que lorsque la méthode asList est appelée, elle retourne la liste de sa propre version de classe statique privée qui ne remplace pas la fonction d'ajout de AbstractList pour stocker l'élément dans le tableau. Donc, par défaut, la méthode add dans la liste abstraite lève une exception.
Ce n'est donc pas une liste de tableaux régulière.
la source
Vous ne pouvez pas supprimer ni ajouter à une liste de tableaux à taille fixe.
Mais vous pouvez créer votre sous-liste à partir de cette liste.
list = list.subList(0, list.size() - (list.size() - count));
* L'autre manière est
cela créera ArrayList qui n'est pas de taille fixe comme Arrays.asList
la source
Arrays.asList()
utilise un tableau de taille fixe en interne.Vous ne pouvez pas ajouter ou supprimer de manière dynamique
Arrays.asList()
Utilisez ceci
Dans,
narraylist
vous pouvez facilement ajouter ou supprimer des éléments.la source
Créer une nouvelle liste et remplir des valeurs valides dans une nouvelle liste a fonctionné pour moi.
Erreur de lancement de code -
Après correction -
la source