[java] Java의 ArrayList에서 ArrayList를 슬라이스하려면 어떻게해야합니까?

ArrayListJava에서 배열 조각을 어떻게 얻 습니까? 구체적으로 다음과 같이하고 싶습니다.

ArrayList<Integer> inputA = input.subList(0, input.size()/2);
// where 'input' is a prepouplated ArrayList<Integer>

그래서 이것이 작동 할 것으로 예상했지만 Java는 List-를 반환 하므로 호환되지 않습니다. 그리고 캐스팅하려고 할 때 Java가 허용하지 않습니다. 나는 ArrayList-내가 무엇을 할 수 있습니까?



답변

Java에서는 API의 구체적인 클래스보다는 인터페이스 유형을 사용하는 것이 좋습니다.

당신의 문제는 ArrayList당신이 실제로 사용해야 할 곳 (아마 많은 곳에서)을 사용하고 있다는 것 List입니다. 결과적으로 목록이 ArrayList.

코드는 다음과 같습니다.

List input = new ArrayList(...);

public void doSomething(List input) {
   List inputA = input.subList(0, input.size()/2);
   ...
}

this.doSomething(input);

문제에 대해 제안한 “해결 방법”은 다음과 같습니다.

new ArrayList(input.subList(0, input.size()/2))

하위 목록을 복사하여 작동합니다. 정상적인 의미에서 슬라이스가 아닙니다. 또한 하위 목록이 크면 복사본을 만드는 데 비용이 많이 듭니다.


당신은 당신이 있음 API에서 제한하는 경우 변경할 수 없습니다 당신이 있도록, 해야 선언 inputAint로서 ArrayList, 당신의 사용자 정의 서브 클래스 구현 할 수있을 ArrayList하는 subList방법의 서브 클래스를 반환합니다 ArrayList. 하나:

  1. 설계, 구현 및 테스트하는 데 많은 작업이 필요할 것입니다.
  2. 이제 클래스의 문서화되지 않은 측면 (따라서 “변경 될 수 있음”) 측면에 대한 종속성이있는 중요한 새 클래스를 코드베이스에 추가했습니다 ArrayList.
  3. ArrayList대신에 하위 클래스의 인스턴스를 만들기 위해 인스턴스를 만드는 코드베이스의 관련 위치를 변경해야합니다 .

“배열 복사”솔루션이 더 실용적입니다. 이것이 진정한 슬라이스가 아니라는 점을 염두에 두십시오.


답변

ArrayList에서 제거해야하는 요소의 startIndex 및 endIndex를 알고있는 경우 방법을 찾았습니다.

하자 al원래의 ArrayList하고 startIndex, endIndex각각 상기 어레이로부터 제거되기 시작 및 종료 인덱스 수 :

al.subList(startIndex, endIndex + 1).clear();


답변

기존 메서드가 없으면 0에서으로 반복 input.size()/2하여 각 연속 요소를 가져와 새 ArrayList에 추가 할 수 있다고 생각합니다 .

편집 : 사실, 나는 당신이 그 목록을 가지고 그것을 사용 하여 ArrayList 생성자 중 하나를 사용하여 새로운 ArrayList를 인스턴스화 할 수 있다고 생각합니다 .


답변

이 게시물은 매우 오래되었지만. 누군가 이걸 찾고 있다면 ..

Guava는 List를 지정된 크기의 하위 목록으로 분할하는 것을 용이하게합니다.

List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
    List<List<Integer>> subSets = Lists.partition(intList, 3);


답변

이것이 내가 그것을 해결 한 방법입니다. 하위 목록이 원래 목록의 요소에 대한 직접적인 참조라는 것을 잊었으므로 작동하지 않는 이유가 이해가됩니다.

ArrayList<Integer> inputA = new ArrayList<Integer>(input.subList(0, input.size()/2));


답변