일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- github action
- stream groupingby
- c++ 빌드
- list remove
- java stream api
- 코드포스
- equals
- SpringBootApplication
- javascript image slider
- Java Wrapper Class
- image slider
- equals override
- lombok Builder
- Java lombok
- github deploy
- java hashCode
- AWS Codedeploy
- java CompletableFuture
- github CI
- java 비동기처리
- kotest
- hashcode override
- Java
- github ec2 deploy
- Github action deploy
- github action codedeploy
- Spring Aspect
- AliasFor
- github CI/CD
- vanilla js image slider
- Today
- Total
기록창고
JAVA List for 문으로 remove하기 본문
List 에 있는 목록 중 원하는 객체를 삭제하는 방법.
맨 처음에는 가장 간단하게 for문으로 돌리면서 찾아서 삭제를 했다.
import java.util.*;
public class test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("A");
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
for(int i=0;i<list.size();i++){
String str = list.get(i);
if(str.equals("A")) list.remove(i);
}
System.out.println(String.join(", ", list));
}
}
위 코드는 list 중 "A"랑 같은게 있으면 삭제해라는 코드이다.
그치만 실제로 출력 결과를 보면 A, B, C, D, E 가 출력된다.
이유는 첫번째 A가 삭제되면서 두번째 A의 인덱스로 1에서 0으로 변경되었기 때문이다..
A A B C D E -> A B C D E
0 1 2 3 4 5 -> 0 1 2 3 4
이렇게 변경되어, i 는 1로 변경된다. 그래서 두번째 A는 발견되지 않고 삭제가 되지 않는다.
for(int i=0;i<list.size();i++){
String str = list.get(i);
if(str.equals("A")) list.remove(i--); // i -> i--
}
// B, C, D, E;
그래서 if문에 걸려 remove가 되면 i를 하나빼서 그 자리부터 다시 돌게 하는 방법도 있다.
이 방법은 왠지 별로 같다..
왜냐하면 아래 만약 i를 가지고 수행하는 로직이 있다면, i-1 값으로 생각하고 코드를 작성해야하기 때문에
불편하고 가독성이 떨어질 거 같다. 그래도 위의 코드에서는 원하는 바를 달성한다.
다른 방법은 iterator를 이용하는 법이다.
for(Iterator<String> it=list.iterator(); it.hasNext();){
String str = it.next();
if(str.equals("A")) it.remove();
}
index를 이용한 for문과 비슷해보인다.
왜 it.remove()를 해도 잘 작동이 될까?
아래 Iterator의 remove 함수 와 next 함수이다.
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
// 삭제되어 lastRet이 -1로 되지않으면, cursor와 lastRet는 1차이 밖에 나지않는다.
}
lastRet
은 마지막으로 리턴한 값의 인덱스이다.cursor
는 다음에 리턴될 값의 인덱스이다.
그래서 remove 함수는 마지막으로 리턴한 값의 인덱스를 지워버리고
현재 커서를 다시 그곳으로 옮겨놓는다.
첫번째 A
it.next() 이후, cursor = 1, lastRet = 0;
it.remove() 이후, 첫번째 A는 사라지고 다시 커서는 0 으로 바꾸고, lastRet은 -1로 바꾼다.
두번째 A
it.next() 이후, cursor = 1, lastRet = 0;
it.remove() 이후는 위와 같은 동작을 한다.
마치 코드가 for 문을 index에서 수정한것 처럼 커서를 -1 해준다.
까보니 잘 모르겠다....
iterator를 쓴것과 안쓴것의 차이를..
가독성이 좋고 .... 흠.. 모르겠다.
추가로 Collection 을 이용하는 방법도 있다.
JAVA 8 부터 지원한다고 한다.
list.removeIf(str -> str.equals("A"));
System.out.println(String.join(", ", list));
매우 많이 간단해졌따... 헣;;
코드도 처음보는 사람도 읽기 쉽다.
만약 아래와 같은 조건이 만족한다면 지워라 라고 코드에 서술해 놓은거 같다.
깔끔하게 이쁘다.
끝!
'JAVA' 카테고리의 다른 글
String.equals() (0) | 2020.01.19 |
---|---|
Collectors GroupingBy (0) | 2020.01.16 |
equals() override (0) | 2019.12.28 |
hashCode() override (0) | 2019.12.27 |
static 에 관하여 (0) | 2019.12.22 |