Unsupported Operation이 표시되는 이유목록에서 요소를 제거하려고 할 때 예외가 발생합니까?
코드는 다음과 같습니다.
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, ", ");
}
알겠네.
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)
이게 어떻게 올바른 방법일까요?자바.15
코드에는 많은 문제가 있습니다.
에서Arrays.asList
고정 크기 목록 반환
API에서:
Arrays.asList
: 지정한 배열에서 지원되는 고정 크기 목록을 반환합니다.
그럴수는 없어요.add
할 수 없다remove
그것으로부터.구조적으로 변경할 수 없습니다.List
.
고치다
작성하다LinkedList
보다 고속으로 서포트remove
.
List<String> list = new LinkedList<String>(Arrays.asList(split));
에서split
정규식을 취득하다
API에서:
: 지정된 정규 표현과 일치하는 문자열로 분할합니다
String.split(String regex)
.
|
리터럴로 분할하려면 , regex 메타 문자입니다.|
, 당신은 그것을 탈출해야 합니다.\|
Java 문자열 리터럴로서"\\|"
.
수정:
template.split("\\|")
보다 뛰어난 알고리즘으로
전화하는 대신remove
랜덤 인덱스를 사용하여 한 번에 한 개씩 범위 내에서 충분한 랜덤 번호를 생성하고, 그 다음 데이터 범위를 통과하는 것이 좋습니다.List
와 함께 한 번listIterator()
,부르기remove()
적절한 지수로.stackoverflow에 관한 질문은 소정의 범위 내에서 랜덤하지만 고유한 번호를 생성하는 방법에 관한 것입니다.
이렇게 하면 알고리즘은O(N)
.
이건 날 여러 번 태웠어. Arrays.asList
변경할 수 없는 목록을 만듭니다.[From Javadoc] : 지정한 배열로 지원되는 고정 크기 목록을 반환합니다.
동일한 내용으로 새 목록 만들기:
newList.addAll(Arrays.asList(newArray));
이렇게 하면 쓰레기가 조금 더 생성되지만 변이시킬 수 있습니다.
수정 불가능한 포장지로 작업하기 때문일 것입니다.
다음 행 변경:
List<String> list = Arrays.asList(split);
다음 행으로 이동합니다.
List<String> list = new LinkedList<>(Arrays.asList(split));
대체는 다음과 같습니다.
List<String> list = Arrays.asList(split);
와 함께
List<String> list = new ArrayList<String>(Arrays.asList(split));
이 문제를 해결합니다.
에 의해 반환된 목록Arrays.asList()
불변할 수도 있어요.한번 해 볼래?
List<String> list = new ArrayList<>(Arrays.asList(split));
asList 메서드에 대해서는 JavaDoc을 읽어주세요.
지정된 어레이에 있는 개체의 {@code List}을(를) 반환합니다.{@code List}의 크기를 수정할 수 없습니다. 즉, 추가 및 제거는 지원되지 않지만 요소를 설정할 수 있습니다.요소를 설정하면 기본 배열이 변경됩니다.
자바6의 제품이지만 안드로이드 자바도 마찬가지인 것 같습니다.
편집
결과 목록의 유형은 다음과 같습니다.Arrays.ArrayList
Arrays.class 내의 프라이빗 클래스입니다.실제로는, 지금까지 사용한 어레이의 리스트 뷰에 지나지 않습니다.Arrays.asList
따라서 어레이를 변경하면 목록도 변경됩니다.또한 어레이의 크기를 조정할 수 없기 때문에 제거 및 추가 작업은 지원되지 않아야 합니다.
Arrays.asList()는 크기에 영향을 미치는 작업을 허용하지 않는 목록을 반환합니다(이는 "수정할 수 없음"과 동일하지 않음).
수 요.new ArrayList<String>(Arrays.asList(split));
, 여러분이 은 '본문 '본문', '본문', '본문', '본문'이 ).O(n^2)
알고리즘이 그 바로 아래에 있습니다.
「 」를 list.size() - count
을 (이것을)라고.k
의 랜덤 ).아, 아, 아, 아, 아, 아, 아, 네.로 몇 만 하면 .k
subList() clear() clear ( ) 。 심술궂게 .O(n)
알고리즘)O(k)
더 정확합니다).
업데이트: 아래에 기술한 바와 같이 이 알고리즘은 목록이 가방을 나타내는 등 요소가 정렬되지 않은 경우에만 의미가 있습니다.반면 목록에 의미 있는 순서가 있는 경우 이 알고리즘은 이를 보존하지 않습니다(대신 다종 다양체의 알고리즘).
업데이트 2: 다시 생각해 보면 더 나은(선형, 순서 유지, 단 O(n) 난수 사용) 알고리즘은 다음과 같습니다.
LinkedList<String> elements = ...; //to avoid the slow ArrayList.remove()
int k = elements.size() - count; //elements to select/delete
int remaining = elements.size(); //elements remaining to be iterated
for (Iterator i = elements.iterator(); k > 0 && i.hasNext(); remaining--) {
i.next();
if (random.nextInt(remaining) < k) {
//or (random.nextDouble() < (double)k/remaining)
i.remove();
k--;
}
}
이 Operation은 되지 않는 하려고 할 때, 사용자의을 할 때 합니다.또한 사용자의 경우 콜을 호출할 수 있습니다.Arrays.asList
.java.util.ArrayList
이됩니다.java.util.Arrays$ArrayList
불변의 리스트입니다.을 사용법
이 문제에 대한 다른 해결책이 있습니다.
List<String> list = Arrays.asList(split);
List<String> newList = new ArrayList<>(list);
연구하다newList
교체하다
List<String> list=Arrays.asList(split);
로.
List<String> list = New ArrayList<>();
list.addAll(Arrays.asList(split));
또는
List<String> list = new ArrayList<>(Arrays.asList(split));
또는
List<String> list = new ArrayList<String>(Arrays.asList(split));
또는 (요소 제거에 더 좋습니다)
List<String> list = new LinkedList<>(Arrays.asList(split));
이 문제는 Arrays.asList() 메서드를 사용하여 Length를 고정하여 목록을 만들고 있다는 것입니다.
반환된 목록이 고정 크기 목록이기 때문에 요소를 추가하거나 제거할 수 없습니다.
사용하고 있는 아래의 코드 블록을 참조해 주세요.
이 반복에서는 예외가 발생합니다.이것은 asList()에 의해 작성된 반복 리스트이기 때문에 삭제 및 추가를 할 수 없기 때문에 고정 배열입니다.
List<String> words = Arrays.asList("pen", "pencil", "sky", "blue", "sky", "dog");
for (String word : words) {
if ("sky".equals(word)) {
words.remove(word);
}
}
새로운 Array List를 도입하고 있기 때문에 반복하면서 변경할 수 있습니다.
List<String> words1 = new ArrayList<String>(Arrays.asList("pen", "pencil", "sky", "blue", "sky", "dog"));
for (String word : words) {
if ("sky".equals(word)) {
words.remove(word);
}
}
,, 온에Arrays.asList
고정 크기 목록을 반환합니다.
리스트를 하는 것 에는, 「」를 사용합니다.addAll
메서드 리스트.
예:
String idList = "123,222,333,444";
List<String> parentRecepeIdList = new ArrayList<String>();
parentRecepeIdList.addAll(Arrays.asList(idList.split(",")));
parentRecepeIdList.add("555");
어레이의 고정 크기 목록에는 제거할 수도, 추가할 수도 없습니다.
그러나 이 목록에서 하위 목록을 만들 수 있습니다.
list = list.subList(0, list.size() - (list.size() - count));
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 = list.subList(0, list.size() - (list.size() - count));
}
return StringUtils.join(list, ", ");
}
*Other 방법은
ArrayList<String> al = new ArrayList<String>(Arrays.asList(template));
이 ArrayList Arrays.asList처럼 아닌 고정 크기를 만들 것이다.
Arraylist narraylist=Arrays.asList().//반환합니다 불변의 arraylist이 변할 수 있는 해결책:narraylist=new ArrayList(Arrays.asList())Arraylist어야 하다;.
코드 Arrays의 무리.
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
그래서 무슨 일이 일어날 때asList 메서드 호출이 그것 자체의 민간 정적 클래스 버전의 AbstractList에서 배열에 요소를 저장하는 데 funcion를 재정의하지 않목록을 반환합니다.그래서 추상적인 목록에서 기본 추가 메서드에서 예외를 throw 합니다.
그래서 그건 규칙적인 배열 목록입니다.
Arrays.asList()
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
수 .Arrays.asList()
이것을 사용하세요
Arraylist<String> narraylist=new ArrayList(Arrays.asList());
»narraylist
당신은 쉽게 또는 제거 항목을 추가할 수 있다.
그리고 새로운 목록에서 유효한 값 종 새로운 만드는 것은 나를 위해 일했다.
코드의 문제를 던지고-
List<String> list = new ArrayList<>();
for (String s: list) {
if(s is null or blank) {
list.remove(s);
}
}
desiredObject.setValue(list);
해결책-
List<String> list = new ArrayList<>();
List<String> newList= new ArrayList<>();
for (String s: list) {
if(s is null or blank) {
continue;
}
newList.add(s);
}
desiredObject.setValue(newList);
언급URL:https://stackoverflow.com/questions/2965747/why-do-i-get-an-unsupportedoperationexception-when-trying-to-remove-an-element-f
'programing' 카테고리의 다른 글
효율성: 어레이와 포인터 비교 (0) | 2022.07.10 |
---|---|
vuejs2 데이터에 하위 구성 요소 동적 삽입($compile 또는 v-html 남용 없음) (0) | 2022.07.10 |
C의 소켓을 통한 구조 전달 (0) | 2022.07.10 |
Vue에 클래스가 존재하는지 여러 요소를 검사하려면 어떻게 해야 합니까? (0) | 2022.07.10 |
Vue 경고 수정 방법:구성요소 렌더링 함수에 무한 업데이트 루프가 있을 수 있습니다. (0) | 2022.07.10 |