안녕하세요! 이전 강의에서는 배열과 같은 데이터 구조를 자세히 살펴보고 이를 사용하는 일반적인 예를 살펴보았습니다. 하지만 이 데이터 구조에는 여러 가지 단점이 있습니다. 이에 대한 대답은 Java에서 ArrayList의 등장이었습니다. 최대한 간단하게 표현하면 Java의 ArrayList는 많은 새로운 기능이 포함된 "업그레이드된" 배열입니다.
Java Arraylist는 일반 배열과 어떻게 다릅니까?
일반적으로 배열은 매우 편리하며 이미 알고 있듯이 이를 사용하여 많은 작업을 수행할 수 있습니다. :) 그러나 배열에는 여러 가지 단점도 있습니다.- 제한된 크기. 배열을 만드는 단계에서 배열에 포함되어야 하는 셀 수를 이미 알아야 합니다. 필요한 양을 과소 평가하면 공간이 충분하지 않습니다. 이를 과대평가하면 배열이 절반만 비어 있는 상태로 남게 되는데, 이는 그다지 나쁘지 않습니다. 결국 필요한 것보다 더 많은 메모리를 할당하게 된다는 것이 밝혀졌습니다.
- 배열에는 요소를 추가하는 방법이 없습니다. 요소를 추가하려는 셀의 인덱스를 항상 명시적으로 지정해야 합니다. 이미 사용된 셀에 원하는 값을 실수로 지정하면 해당 셀을 덮어쓰게 됩니다.
- 요소를 제거하는 방법은 없습니다. 값은 "0으로 설정"만 가능합니다.
public class Cat {
private String name;
public Cat(String name) {
this.name = name;
}
public static void main(String[] args) {
Cat[] cats = new Cat[3];
cats[0] = new Cat("Thomas");
cats[1] = new Cat("Hippopotamus");
cats[2] = new Cat("Philip Markovich");
cats[1] = null;
System.out.println(Arrays.toString(cats));
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
결론:
[Cat{name='Томас'}, null, Cat{name='Фorпп Маркович'}]
이러한 모든 단점은 ArrayList를 사용하여 제거할 수 있습니다. 매우 간단하게 생성됩니다.
ArrayList<Cat> cats = new ArrayList<Cat>();
이제 객체를 저장할 목록을 만들었습니다 Cat
. 주의하세요:ArrayList는 자동으로 확장 가능하므로 크기를 지정하지 않습니다. 이것이 어떻게 가능한지? 용이하게. 놀라실 겁니다. 하지만 ArrayList는 일반 배열을 기반으로 합니다. :) 예, 그 안에 요소가 저장되는 배열이 있습니다. 그러나 ArrayList에는 이를 사용하기 위한 특별한 메커니즘이 있습니다.
- 이 내부 배열이 가득 차면 ArrayList는 자체 내에 새 배열을 만듭니다. 크기 = (이전 배열의 크기 * 1.5) +1.
- 모든 데이터는 이전 어레이에서 새 어레이로 복사됩니다.
- 이전 배열은 가비지 수집기에 의해 제거됩니다.
add()
.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<Cat>();
cats.add(new Cat("Hippopotamus"));
}
새 요소가 목록 끝에 추가됩니다. 이제 넘칠 위험이 없으므로 이 메커니즘은 완전히 안전합니다. 그건 그렇고, ArrayList는 인덱스로 객체를 검색할 수 있을 뿐만 아니라 그 반대도 마찬가지입니다. 객체를 참조하여 ArrayList에서 객체의 인덱스를 찾을 수 있습니다! 이를 위해 메소드를 구현합니다. indexOf()
원하는 객체에 대한 링크를 전달하고 indexOf()
해당 인덱스를 반환합니다.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
int thomasIndex = cats.indexOf(thomas);
System.out.println(thomasIndex);
}
결론:
0
맞습니다. 개체는 thomas
실제로 셀에 저장됩니다 0
. 어레이에는 단점뿐만 아니라 확실한 장점도 있습니다. 그 중 하나는 인덱스로 요소를 검색하는 것입니다. 인덱스, 즉 메모리의 특정 주소를 가리키기 때문에 이러한 배열 검색은 매우 빠릅니다. Java의 ArrayList도 이 작업을 수행할 수 있습니다! 이를 위해 다음 메소드를 구현합니다 get()
.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
Cat secondCat = cats.get(1);
System.out.println(secondCat);
}
결론:
Cat{name='Бегемот'}
또한 ArrayList에 특정 객체가 포함되어 있는지 여부를 쉽게 확인할 수 있습니다. 이는 다음 방법을 사용하여 수행됩니다 contains()
.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
cats.remove(pushok);
System.out.println(cats.contains(pushok));
}
boolean
이 메서드는 요소가 ArrayList의 내부 배열에 포함되어 있는지 확인하고 - true
또는 형식으로 결과를 반환합니다 false
. 결론:
false
그리고 삽입에 관한 또 다른 중요한 점. ArrayList를 사용하면 배열 끝뿐만 아니라 인덱스별로 모든 셀에 데이터를 삽입할 수 있습니다. 이를 위한 두 가지 방법이 있습니다:
add(int index, Cat element)
set(int index, Cat element)
set()
셀에 저장된 이전 값을 덮어쓴다는 점입니다. 그리고 처음부터 삽입하면 배열의 끝 부분 add()
부터 시작하여 모든 요소가 이동 하고 결과 빈 셀에 필요한 개체가 추가됩니다. [index]
예는 다음과 같습니다.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
System.out.println(cats.toString());
cats.set(0, philipp);//Now we have a list of 2 cats. We add the 3rd via set:
System.out.println(cats.toString());
}
결론:
[[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='Фorпп Маркович'}, Cat{name='Бегемот'}]
우리는 고양이 2마리의 목록을 가지고 있었고, 방법을 통해 또 다른 고양이를 set()
셀에 삽입했습니다 0
. 결과적으로 이 셀에 저장된 이전 값이 새 값으로 대체되었습니다.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
System.out.println(cats.toString());
cats.add(0, philipp);//Now we have a list of 2 cats. Add the 3rd via add
System.out.println(cats.toString());
}
그러나 그것은 add()
다르게 작동했습니다. 그는 모든 요소를 오른쪽으로 이동한 다음 새 값을 셀에 썼습니다 0
. 결론:
[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='Фorпп Маркович'}, Cat{name='Томас'}, Cat{name='Бегемот'}]
목록을 완전히 지우려면 다음 방법을 사용하십시오 clear()
.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
cats.clear();
System.out.println(cats.toString());
}
결론:
[]
모든 콘텐츠가 목록에서 제거되었습니다. 그런데 주의하세요: 배열과 달리 ArrayList에서는 toString() 메서드가 재정의되고 즉시 목록을 문자열 형식으로 표시합니다. 배열의 경우 이를 위해 Arrays 클래스를 사용해야 했습니다. 그리고 우리가 배열을 기억했기 때문에 Java에서는 배열과 ArrayList 사이를 쉽게 "전환"할 수 있습니다. 즉, 배열을 다른 것으로 변환할 수 있습니다. Arrays 클래스에는 이를 위한 Arrays.asList() 메서드가 있습니다. 도움을 받아 배열의 내용을 목록으로 가져와 이를 ArrayList의 생성자에 전달합니다.
public static void main(String[] args) {
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
Cat[] catsArray = {thomas, behemoth, philipp, pushok};
ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
System.out.println(catsList);
}
결론:
[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
반대의 경우도 있습니다. ArrayList 객체에서 배열을 가져옵니다. 이렇게 하려면 toArray() 메서드를 사용합니다.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
Cat[] catsArray = cats.toArray(new Cat[0]);
System.out.println(Arrays.toString(catsArray));
}
참고: toArray() 메소드에 빈 배열을 전달했습니다. 그것은 실수가 아닙니다. ArrayList 클래스 내에서 이 메서드는 빈 배열을 전달하면 성능이 향상되는 방식으로 구현됩니다. 지금은 미래를 위해 이것을 기억해 두세요(그러나 특정 크기를 전송할 수도 있으므로 작동합니다). 크기에 대해 말하면. 목록의 현재 크기는 다음 메소드를 사용하여 확인할 수 있습니다 size()
.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
System.out.println(cats.size());
}
length
배열 속성과 달리 ArrayList.size() 메서드는 ArrayList를 생성할 때 이를 지정하지 않기 때문에 초기 용량이 아닌 요소 수를 정확하게 반환한다는 점을 여기서 이해하는 것이 중요합니다 . 그건 그렇고, 일반적으로 그것을 표시하는 것이 가능합니다. ArrayList에는 해당 생성자가 있습니다. 그러나 새 요소를 추가하는 것과 관련된 동작은 변경되지 않습니다.
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>(2);//create an ArrayList with an initial capacity of 2
Cat thomas = new Cat("Thomas");
Cat behemoth = new Cat("Hippopotamus");
Cat philipp = new Cat("Philip Markovich");
Cat pushok = new Cat("Fluff");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
System.out.println(cats.size());
}
콘솔 출력:
4
우리는 2개의 요소로 목록을 만들었지만 필요할 때 쉽게 확장할 수 있었습니다. 또 다른 점은 처음에 매우 작은 목록을 생성한 경우 확장 작업을 더 자주 수행해야 하며 이로 인해 일정량의 리소스가 소비된다는 것입니다. 이번 강의에서는 ArrayList에서 요소를 제거하는 과정에 대해서는 거의 다루지 않았습니다. 물론 이것은 건망증 때문이 아닙니다. 이 주제는 별도의 강의로 분리되어 있어 더 자세히 읽어보실 수 있습니다 :)
GO TO FULL VERSION