Eu tenho este código:
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, ", ");
}
Eu entendi isso:
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)
Como seria isso da maneira correta? Java.15
Respostas:
Alguns problemas com seu código:
Ao
Arrays.asList
retornar uma lista de tamanho fixoNa API:
Você não pode
add
fazer isso; você não poderemove
disso. Você não pode modificar estruturalmente oList
.Consertar
Crie um
LinkedList
, que suporte mais rápidoremove
.Ao
split
tomar regexNa API:
|
é um metacaractere regex; se você deseja dividir em um literal|
, você deve escapá-lo para\|
, o que, como um literal de string Java, é"\\|"
.Consertar:
Em um algoritmo melhor
Em vez de chamar
remove
um de cada vez com índices aleatórios, é melhor gerar números aleatórios suficientes no intervalo e, em seguida, percorrer aList
única vez com alistIterator()
, chamandoremove()
nos índices apropriados. Há perguntas sobre o stackoverflow sobre como gerar números aleatórios, mas distintos, em um determinado intervalo.Com isso, seu algoritmo seria
O(N)
.fonte
Random
toda vez. Faça umstatic
campo e semeie apenas uma vez.Este me queimou muitas vezes.
Arrays.asList
cria uma lista não modificável. No Javadoc: retorna uma lista de tamanho fixo apoiada pela matriz especificada.Crie uma nova lista com o mesmo conteúdo:
Isso criará um pouco de lixo extra, mas você poderá modificá-lo.
fonte
Provavelmente porque você está trabalhando com um invólucro não modificável .
Mude esta linha:
para esta linha:
fonte
unmodifiable
eimmutable
.unmodifiable
significa exatamente "modificável, mas não estruturalmente".unmodifiableList
wrapper e tentar umset
; jogaUnsupportedOperationException
. Estou certo de queCollections.unmodifiable*
realmente significa imutabilidade total, não apenas estrutural.Eu acho que substituindo:
com
resolve o problema.
fonte
A lista retornada por
Arrays.asList()
pode ser imutável. Você poderia tentarfonte
Basta ler o JavaDoc para o método asList:
Este é do Java 6, mas parece que é o mesmo para o java android.
EDITAR
O tipo da lista resultante é
Arrays.ArrayList
, que é uma classe privada dentro de Arrays.class. Na prática, nada mais é do que uma exibição em lista na matriz com a qual você passouArrays.asList
. Com uma conseqüência: se você alterar a matriz, a lista também será alterada. E como uma matriz não é redimensionável, a operação de remoção e adição não deve ser suportada.fonte
Arrays.asList () retorna uma lista que não permite operações que afetam seu tamanho (observe que isso não é o mesmo que "não modificável").
Você pode fazer
new ArrayList<String>(Arrays.asList(split));
para criar uma cópia real, mas vendo o que você está tentando fazer, aqui está uma sugestão adicional (você tem umO(n^2)
algoritmo logo abaixo).Você deseja remover
list.size() - count
(vamos chamar issok
) elementos aleatórios da lista. Basta escolher o maior número de elementos aleatórios e trocá-los para ask
posições finais da lista e excluir todo o intervalo (por exemplo, usando subList () e clear () nele). Isso o tornaria umO(n)
algoritmo enxuto e médio (O(k)
é mais preciso).Atualização : Conforme observado abaixo, esse algoritmo só faz sentido se os elementos não estiverem ordenados, por exemplo, se a Lista representar um Saco. Se, por outro lado, a Lista tiver uma ordem significativa, esse algoritmo não a preservará (o algoritmo dos pologenelubricantes, em vez disso).
Atualização 2 : Então, retrospectivamente, um algoritmo melhor (linear, mantendo a ordem, mas com O (n) números aleatórios)) seria algo como isto:
fonte
ArrayList
. Muito mais simples do que minha sugestão. Eu acho que resultaria na reordenação dos elementos.Eu tenho outra solução para esse problema:
trabalhar em
newList
;)fonte
Essa UnsupportedOperationException ocorre quando você tenta executar alguma operação na coleção onde não é permitido e, no seu caso, quando você chama
Arrays.asList
, não retorna ajava.util.ArrayList
. Retorna umajava.util.Arrays$ArrayList
lista imutável. Você não pode adicionar e nem remover.fonte
Sim,
Arrays.asList
retornando uma lista de tamanho fixo.Além de usar uma lista vinculada, basta usar a
addAll
lista de métodos.Exemplo:
fonte
Substituir
para
ou
ou
ou (Melhor para remover elementos)
fonte
Arraylist narraylist = Arrays.asList (); // Retorna arraylist imutável Para torná-lo uma solução mutável, seria: Arraylist narraylist = new ArrayList (Arrays.asList ());
fonte
A seguir, trecho de código de matrizes
Então, o que acontece é que, quando o método asList é chamado, ele retorna a lista de sua própria versão de classe estática privada, que não substitui a função add de AbstractList para armazenar o elemento na matriz. Portanto, por padrão, o método add na lista abstrata lança exceção.
Portanto, não é uma lista regular de matrizes.
fonte
Você não pode remover nem adicionar a uma lista de matrizes de tamanho fixo.
Mas você pode criar sua sublist a partir dessa lista.
list = list.subList(0, list.size() - (list.size() - count));
* Outra maneira é
isso criará ArrayList que não é de tamanho fixo como Arrays.asList
fonte
Arrays.asList()
usa matriz de tamanho fixo internamente.Você não pode adicionar ou remover dinamicamente deste
Arrays.asList()
Usa isto
Em
narraylist
você pode facilmente adicionar ou remover itens.fonte
Criar uma nova lista e preencher valores válidos na nova lista funcionou para mim.
Erro de lançamento de código -
Após correção -
fonte