수색…


소개

목록정렬 된 값 모음입니다. Java에서 목록은 Java Collections Framework의 일부입니다. 목록은 구현 java.util.List 확장 인터페이스, java.util.Collection .

통사론

  • ls.add (E 요소); // 요소를 추가합니다.
  • ls.remove (E 요소); // 요소를 제거합니다.
  • for (E element : ls) {} // 각 원소를 반복한다.
  • ls.toArray (new String [ls.length]); // 문자열 목록을 문자열 배열로 변환합니다.
  • ls.get (int index); // 지정된 인덱스에있는 요소를 반환합니다.
  • ls.set (int index, E element); // 지정된 위치의 요소를 바꿉니다.
  • ls.isEmpty (); // 배열에 요소가 없으면 true를 반환하고 그렇지 않으면 false를 반환합니다.
  • ls.indexOf (Object o); // 지정된 요소 o의 첫 번째 위치에 대한 인덱스를 반환하거나, 존재하지 않으면 -1을 반환합니다.
  • ls.lastIndexOf (Object o); // 지정된 요소 o의 마지막 위치의 인덱스를 반환하거나, 존재하지 않으면 -1을 반환합니다.
  • ls.size (); // List에있는 요소의 수를 반환합니다.

비고

목록 은 값의 정렬 된 컬렉션을 저장하는 객체입니다. "주문 됨"은 값이 특정 순서로 저장됨을 의미합니다. 한 항목이 먼저오고 두 번째는 두 번째 등입니다. 개별 값은 일반적으로 "요소"라고합니다. Java 목록은 일반적으로 다음 기능을 제공합니다.

  • 목록에는 0 개 이상의 요소가 포함될 수 있습니다.
  • 목록에 중복 값이 ​​포함될 수 있습니다. 즉, 요소를 두 번 이상 목록에 삽입 할 수 있습니다.
  • 목록은 요소를 특정 순서로 저장합니다. 즉, 요소 ​​하나가 먼저오고, 다음 요소가 오게됩니다.
  • 각 요소에는 목록 내의 위치를 ​​나타내는 인덱스 가 있습니다. 첫 번째 요소에는 인덱스 0이 있고, 다음 요소에는 인덱스 1이 있습니다.
  • 목록을 사용하면 목록의 시작, 끝 또는 모든 색인에 요소를 삽입 할 수 있습니다.
  • 목록에 특정 값이 들어 있는지 테스트하는 것은 일반적으로 목록의 각 요소를 검사하는 것을 의미합니다. 즉,이 검사를 수행하는 시간은 O (n) 이며 목록의 크기에 비례합니다.

끝 이외의 다른 지점에서 값을 목록에 추가하면 다음 요소를 모두 "아래로"또는 "오른쪽으로"이동합니다. 즉, 인덱스 n은 요소를 추가하는 등의 인덱스, N + 1N에 인덱스로 사용될 수있는 요소를 이동시킨다. 예 :

List<String> list = new ArrayList<>();
list.add("world");
System.out.println(list.indexOf("world"));      // Prints "0"
// Inserting a new value at index 0 moves "world" to index 1
list.add(0, "Hello");
System.out.println(list.indexOf("world"));      // Prints "1"
System.out.println(list.indexOf("Hello"));      // Prints "0"

일반 목록 정렬

Collections 클래스는 목록을 정렬하는 두 가지 표준 정적 메서드를 제공합니다.

  • sort(List<T> list) T extends Comparable<? super T> 있는 곳의리스트에 적용 가능 T extends Comparable<? super T> ,
  • sort(List<T> list, Comparator<? super T> c) 모든 유형의 목록에 적용 할 수 있습니다.

전자를 적용하려면 정렬되는 목록 요소의 클래스를 수정해야합니다. 이는 항상 가능하지는 않습니다. 또한 기본 정렬, 다른 상황에서 다른 정렬 순서가 필요할 수도 있고 정렬이 하나의 작업 일 수도 있기 때문에 바람직하지 않을 수도 있습니다.

다음 클래스의 인스턴스 인 객체를 정렬하는 작업이 있다고 가정 해보십시오.

public class User {
    public final Long id;
    public final String username;

    public User(Long id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return String.format("%s:%d", username, id);
    }
}

Collections.sort(List<User> list) 를 사용하려면 User 클래스를 수정하여 Comparable 인터페이스를 구현해야합니다. 예를 들어

public class User implements Comparable<User> {
    public final Long id;
    public final String username;

    public User(Long id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return String.format("%s:%d", username, id);
    }

    @Override
    /** The natural ordering for 'User' objects is by the 'id' field. */
    public int compareTo(User o) {
        return id.compareTo(o.id);
    }
}

String , Long , Integer 와 같은 많은 표준 Java 클래스는 Comparable 인터페이스를 구현하므로 기본적으로 해당 요소의 목록을 정렬 할 수 있으며 다른 클래스에서 compare 또는 compareTo 구현을 단순화합니다.

위의 수정을 통해 클래스 자연 순서 에 따라 User 객체 목록을 쉽게 정렬 할 수 있습니다. (이 경우 id 값을 기반으로 정렬되도록 정의했습니다.) 예 :

List<User> users = Lists.newArrayList(
    new User(33L, "A"),
    new User(25L, "B"),
    new User(28L, ""));
Collections.sort(users);

System.out.print(users);
// [B:25, C:28, A:33]

그러나 User 객체를 id 아닌 name 으로 정렬하려고한다고 가정합니다. 또는 클래스를 변경하여 Comparable 을 구현할 수 없었던 것으로 가정합니다.

Comparator 인수를 사용하는 sort 메소드가 유용합니다.

Collections.sort(users, new Comparator<User>() {
    @Override
    /* Order two 'User' objects based on their names. */
    public int compare(User left, User right) {
        return left.username.compareTo(right.username);
    }
});
System.out.print(users);
// [A:33, B:25, C:28]
Java SE 8

Java 8에서는 익명 클래스 대신 람다 를 사용할 수 있습니다. 후자는 one-liner로 감소합니다.

Collections.sort(users, (l, r) -> l.username.compareTo(r.username));

더욱이, Java 8에서는 List 인터페이스에 기본 sort 메소드를 추가하여 정렬을 훨씬 더 단순화합니다.

users.sort((l, r) -> l.username.compareTo(r.username))

목록 만들기

귀하의 목록 유형을주는

목록을 만들려면 유형 (모든 클래스, 예 : String )이 필요합니다. 이것은 귀하의 List 유형입니다. List 는 지정된 유형의 객체 만 저장합니다. 예 :

List<String> strings;

"string1" , "hello world!" 저장할 수 "hello world!" , "goodbye" 등이 있지만 9.2 저장할 수는 없습니다.

List<Double> doubles;

9.2 저장할 수 있지만 "hello world!" 저장할 수 없습니다 "hello world!" .

목록 초기화하기

위의 목록에 뭔가를 추가하려고하면 stringsdoubles 모두 null 이기 때문에 NullPointerException이 발생합니다!

목록을 초기화하는 방법에는 두 가지가 있습니다.

옵션 1 : List를 구현하는 클래스 사용

List 는 생성자가 아니라 클래스가 재정의해야하는 메서드를 포함하는 인터페이스입니다. ArrayList 는 가장 일반적으로 사용되는 List 이지만 LinkedList 도 일반적입니다. 그래서 우리는 다음과 같이 목록을 초기화합니다.

List<String> strings = new ArrayList<String>();

또는

List<String> strings = new LinkedList<String>();
Java SE 7

Java SE 7부터는 다이아몬드 연산자를 사용할 수 있습니다.

List<String> strings = new ArrayList<>();

또는

List<String> strings = new LinkedList<>();

옵션 2 : Collections 클래스 사용

Collections 클래스는 List 변수없이 List를 만드는 두 가지 유용한 메소드를 제공합니다.

  • emptyList() : 빈 목록을 반환합니다.
  • singletonList(T) : singletonList(T) 유형의 목록을 만들고 지정된 요소를 추가합니다.

기존 List 을 사용하여 데이터를 채우는 방법

  • addAll(L, T...) : 지정된 모든 요소를 ​​첫 번째 매개 변수로 전달 된 목록에 추가합니다.

예 :

import java.util.List;
import java.util.Collections;

List<Integer> l = Collections.emptyList();
List<Integer> l1 = Collections.singletonList(42);
Collections.addAll(l1, 1, 2, 3);

위치 액세스 작업

List API에는 위치 액세스 조작을위한 8 가지 메소드가 있습니다.

  • add(T type)
  • add(int index, T type)
  • remove(Object o)
  • remove(int index)
  • get(int index)
  • set(int index, E element)
  • int indexOf(Object o)
  • int lastIndexOf(Object o)

그래서 우리가리스트를 가지고 있다면 :

List<String> strings = new ArrayList<String>();

그리고 우리는 "Hello world!"라는 문자열을 추가하기를 원했습니다. 와 "안녕 세상!" 그것으로, 우리는 그렇게 할 것입니다 :

strings.add("Hello world!");
strings.add("Goodbye world!");

그리고 우리 목록에는 두 가지 요소가 포함됩니다. 이제 "프로그램 시작"을 추가하고 싶다고 말하면됩니다. 목록 앞에 . 우리는 이렇게 할 것입니다 :

strings.add(0, "Program starting!");

참고 : 첫 번째 요소는 0입니다.

자, 만약 우리가 "안녕히 계십시오!" 라인, 우리는 이렇게 할 수 :

strings.remove("Goodbye world!");

그리고 첫 번째 줄을 없애고 싶다면 (이 경우 "프로그램 시작!"이라고 할 수 있습니다. 다음과 같이 할 수 있습니다 :

strings.remove(0);

노트 :

  1. 리스트 요소의 추가와 삭제는리스트를 변경해,리스트가 동시에 반복 처리되고있는 경우에 ConcurrentModificationException 가되는 일이 있습니다.

  2. 목록 클래스, 사용 된 방법 및 목록의 시작, 끝 또는 중간에 요소 추가 / 제거 여부에 따라 요소 추가 및 제거는 O(1) 또는 O(N) 일 수 있습니다.

지정된 위치에서 목록의 요소를 검색하려면 E get(int index); List API의 메소드 예 :

strings.get(0);

목록의 첫 번째 요소를 반환합니다.

set(int index, E element); 를 사용하여 지정된 위치의 모든 요소를 ​​바꿀 수 있습니다 set(int index, E element); . 예 :

strings.set(0,"This is a replacement");

그러면 목록의 첫 번째 요소로 "This is a replacement"문자열이 설정됩니다.

참고 : set 메서드는 0 위치에 요소를 덮어 씁니다. 새 String을 0 위치에 추가하지 않고 이전 위치를 1 위치로 푸시합니다.

int indexOf(Object o); 인수로 전달 된 객체가 처음 나타나는 위치를 반환합니다. 목록에 오브젝트가 _ 생하지 않으면 -1 값이 리턴됩니다. 앞의 예제를 계속하면 다음을 호출합니다.

strings.indexOf("This is a replacement")

0은 우리 목록의 0 번째 위치에 "This is a replacement"문자열을 설정할 때 반환 될 것으로 예상됩니다. 목록에 하나 이상의 항목이있는 경우 int indexOf(Object o); 언급 된 바와 같이 첫 번째 발생 색인이 반환됩니다. int lastIndexOf(Object o) 를 호출하면 목록에서 마지막으로 발견 된 색인을 검색 할 수 있습니다. 그래서 우리가 다른 "This is a replacement"를 추가하면 :

strings.add("This is a replacement");
strings.lastIndexOf("This is a replacement");

이번에는 1이 반환되고 0은 반환되지 않습니다.

목록의 요소 반복하기

예를 들어, "hello", "how", "are", "you?"네 요소가 포함 된 String 유형의 List가 있다고 가정 해 보겠습니다.

각 요소를 반복하는 가장 좋은 방법은 for-each 루프를 사용하는 것입니다.

public void printEachElement(List<String> list){
    for(String s : list){
        System.out.println(s);
    }
}

어느 것이 인쇄 할 것인가?

hello,
how
are
you?

같은 줄에 모두 인쇄하려면 StringBuilder를 사용할 수 있습니다.

public void printAsLine(List<String> list){
    StringBuilder builder = new StringBuilder();
    for(String s : list){
        builder.append(s);
    }
    System.out.println(builder.toString());
}

인쇄 할 것입니다 :

hello, how are you?

또는 요소 인덱스 작성 ( ArrayList의 i 번째 인덱스에서 요소 액세스에 설명 된대로)을 사용하여 목록을 반복 할 수 있습니다. 경고 :이 방법은 링크 된 목록에 비효율적입니다.

목록 A에있는 목록 B에서 요소 제거

당신은이 목록의 A와 B가 있고, 당신은 B에서이 경우 방법은 당신이에있는 모든 요소를 제거한다고 가정하자

 List.removeAll(Collection c);

#예:

public static void main(String[] args) {
    List<Integer> numbersA = new ArrayList<>();
    List<Integer> numbersB = new ArrayList<>();
    numbersA.addAll(Arrays.asList(new Integer[] { 1, 3, 4, 7, 5, 2 }));
    numbersB.addAll(Arrays.asList(new Integer[] { 13, 32, 533, 3, 4, 2 }));
    System.out.println("A: " + numbersA);
    System.out.println("B: " + numbersB);

    numbersB.removeAll(numbersA);
    System.out.println("B cleared: " + numbersB);
    }

이거 인쇄 할거야.

A : [1, 3, 4, 7, 5, 2]

B : [13, 32, 533, 3, 4, 2]

B 삭제 : [13, 32, 533]

2 개의 목록 사이의 공통 요소 찾기

A와 B의 두 목록이 있고 두 목록에 존재하는 요소를 찾아야한다고 가정합니다.

List.retainAll() 메서드를 호출하면됩니다.

예:

public static void main(String[] args) {
    List<Integer> numbersA = new ArrayList<>();
    List<Integer> numbersB = new ArrayList<>();
    numbersA.addAll(Arrays.asList(new Integer[] { 1, 3, 4, 7, 5, 2 }));
    numbersB.addAll(Arrays.asList(new Integer[] { 13, 32, 533, 3, 4, 2 }));

    System.out.println("A: " + numbersA);
    System.out.println("B: " + numbersB);
    List<Integer> numbersC = new ArrayList<>();
    numbersC.addAll(numbersA);
    numbersC.retainAll(numbersB);

    System.out.println("List A : " + numbersA);
    System.out.println("List B : " + numbersB);
    System.out.println("Common elements between A and B: " + numbersC);

}

정수 목록을 문자열 목록으로 변환

List<Integer> nums = Arrays.asList(1, 2, 3);
List<String> strings = nums.stream()
    .map(Object::toString)
    .collect(Collectors.toList());

그건:

  1. 목록에서 스트림 만들기
  2. Object::toString 사용해 각 요소를 매핑한다
  3. Collectors.toList() 사용하여 List String 값을 수집하십시오.

ArrayList에서 요소 만들기, 추가 및 제거

ArrayList 는 Java의 inbuilt 데이터 구조 중 하나입니다. 요소 (객체)를 저장하기 위해 동적 배열 (데이터 구조의 크기를 먼저 선언 할 필요가없는)입니다.

그것은 AbstractList 클래스를 확장하고 List 인터페이스를 구현합니다. ArrayList 에는 삽입 순서를 유지하는 중복 요소가 포함될 수 있습니다. ArrayList 클래스는 비 동기화되어 있으므로 ArrayList 와의 동시성을 처리 할 때는주의를 기울여야합니다. ArrayList 는 인덱스 단위로 작동하므로 임의 액세스가 허용됩니다. 요소가 배열 목록에서 제거 될 때 자주 발생하는 이동 때문에 ArrayList 에서 조작이 느립니다.

다음과 같이 ArrayList 를 만들 수 있습니다.

List<T> myArrayList = new ArrayList<>();

여기서 T ( Generics )는 ArrayList 내에 저장 될 형식입니다.

ArrayList 의 형태는 임의의 Object가 될 수 있습니다. 형식은 원시 형식이 될 수 없습니다 ( 래퍼 클래스를 대신 사용하십시오).

ArrayList 요소를 추가하려면 add add() 메서드를 사용 add() .

myArrayList.add(element);

또는 특정 색인에 항목을 추가하려면 :

myArrayList.add(index, element); //index of the element should be an int (starting from 0)

ArrayList 에서 항목을 제거하려면 remove remove() 메서드를 사용합니다.

myArrayList.remove(element);

또는 특정 색인에서 항목을 제거하려면 다음을 수행하십시오.

myArrayList.remove(index); //index of the element should be an int (starting from 0)

List 요소의 적절한 대체

이 예제는 대체 요소가 대체되는 요소와 동일한 위치에 있는지 확인하면서 List 요소를 대체하는 것입니다.

다음 방법을 사용하여이 작업을 수행 할 수 있습니다.

  • set (int index, T type)
  • int indexOf (T 형)

요소 "Program starting!", "Hello world!"를 포함하는 ArrayList 를 생각해보십시오. 와 "안녕 세상!"

List<String> strings = new ArrayList<String>();
strings.add("Program starting!");
strings.add("Hello world!");
strings.add("Goodbye world!");

바꾸려는 요소의 색인을 알고 있다면 간단히 set 을 다음과 같이 사용할 수 있습니다.

strings.set(1, "Hi world");

색인을 모른다면 먼저 색인을 검색 할 수 있습니다. 예 :

int pos = strings.indexOf("Goodbye world!");
if (pos >= 0) {
    strings.set(pos, "Goodbye cruel world!");
}

노트:

  1. set 조작으로 ConcurrentModificationException 는 발생하지 않습니다.
  2. set 연산은 ArrayList 대해서는 빠르지 만 ( O(1) ), LinkedList 대해서는 느립니다 ( O(N) ).
  3. ArrayList 또는 LinkedList 에 대한 indexOf 검색은 느립니다 ( O(N) ).

수정 불가능한 목록 만들기

Collections 클래스는 목록을 수정할 수 없도록 만드는 방법을 제공합니다.

List<String> ls = new ArrayList<String>();
List<String> unmodifiableList = Collections.unmodifiableList(ls);

하나의 항목으로 수정할 수없는 목록을 원하면 다음을 사용할 수 있습니다.

List<String> unmodifiableList = Collections.singletonList("Only string in the list");

목록에서 객체를 움직입니다.

Collections 클래스를 사용하면 다양한 메서드 (목록은 ls)를 사용하여 목록에서 객체를 이동할 수 있습니다.

목록 반전 :

Collections.reverse(ls);

목록에있는 요소의 위치 회전

rotate 메소드에는 정수 인수가 필요합니다. 이것은 라인을 따라 이동하는 지점이 얼마나 많은 지입니다. 예를 들면 다음과 같습니다.

List<String> ls = new ArrayList<String>();
ls.add(" how");
ls.add(" are");
ls.add(" you?");
ls.add("hello,");
Collections.rotate(ls, 1);

for(String line : ls) System.out.print(line);
System.out.println();

그러면 "안녕, 잘 지냈니?"라는 문구가 인쇄됩니다.

목록에서 요소 주위를 섞기

위의 동일한 목록을 사용하여 목록의 요소를 임의로 섞을 수 있습니다.

Collections.shuffle(ls);

우리는 java.util.Random 객체를 제공하여 무작위로 객체를 배치 할 수 있습니다 :

Random random = new Random(12); 
Collections.shuffle(ls, random);

List를 구현하는 클래스 - 찬반론

List 인터페이스는 다른 클래스에 의해 구현됩니다. 각각은 서로 다른 전략으로 구현하고 서로 다른 장단점을 제공 할 수있는 자체 방식을 가지고 있습니다.


List를 구현하고있는 클래스

다음은 java.util.List 인터페이스를 구현하는 Java SE 8의 모든 public 클래스입니다.

  1. 추상 클래스 :
    • AbstractList
    • AbstractSequentialList
  2. 구체적인 수업 :
    • ArrayList
    • AttributeList
    • CopyOnWriteArrayList
    • LinkedList
    • RoleList
    • RoleUnresolvedList
    • 스택
    • 벡터

시간 복잡성의 관점에서 각 구현의 장단점

ArrayList

public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable

ArrayList 는, List 인터페이스의 사이즈 변경 가능한 배열 구현입니다. 리스트를 배열에 저장하면, ArrayList 는 배열의 크기를 조작하기위한 메소드 ( List 인터페이스를 구현하는 메소드 이외에)를 제공합니다.

Integer의 ArrayList를 크기 100으로 초기화하십시오.

List<Integer> myList = new ArrayList<Integer>(100); // Constructs an empty list with the specified initial capacity.

- PROS :

크기, isEmpty, get , set , iterator 및 listIterator 작업은 일정한 시간 내에 실행됩니다. 따라서 목록의 각 요소를 가져오고 설정하는 데 소요되는 시간 은 동일 합니다 .

int e1 = myList.get(0);  //   \
int e2 = myList.get(10); //    | => All the same constant cost => O(1)
myList.set(2,10);        //   /

- 단점 :

배열의 크기에 요소를 추가하는 배열 (정적 구조)을 구현하면 모든 배열에 대해 새로운 할당을 수행해야하기 때문에 많은 비용이 듭니다. 그러나 문서에서 :

add 연산은 상각 된 상수 시간에 실행됩니다. 즉, n 요소를 추가하려면 O (n) 시간이 필요합니다.

요소를 제거하려면 O (n) 시간이 필요합니다.


AttributeList

올 때


CopyOnWriteArrayList

올 때


LinkedList

public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable

LinkedList 는 노드라고하는 순차적으로 링크 된 레코드로 구성된 링크 된 데이터 구조를 이중 연결 목록 으로 구현합니다.

정수의 LinkedList 초기화

List<Integer> myList = new LinkedList<Integer>(); // Constructs an empty list.

- PROS :

목록 앞 또는 끝에 요소를 추가하거나 제거하면 일정 시간이 있습니다.

myList.add(10);  // \
myList.add(0,2); //  | => constant time => O(1)
myList.remove(); // /

- 단점 : 문서에서 :

목록에 색인을 생성하는 작업은 시작 또는 끝 중 지정된 색인에 가까운 쪽부터 목록을 탐색합니다.

다음과 같은 작업 :

myList.get(10);    // \
myList.add(11,25); //  | => worst case done in O(n/2)
myList.set(15,35); // /

RoleList

올 때


RoleUnresolvedList

올 때


스택

올 때


벡터

올 때




Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow