2010-04-14 1 views
4

에서 요소의 집합을 제거하는 가장 효율적인 방법은 무엇입니까이 같은 인덱스 위치 3,4의 요소를 제거하는 가장 효율적인 방법은 무엇자바 - 나는했습니다 배열 []

Object[] myObjects = ...(initialized in some way)... 
int[] elemToRemove = new int[]{3,4,6,8,...} 

, 6,8 ... myObjects에서?

내가

public Object[] removeElements(Object[] object, int[] elementsToRemove) {...}

같은 오브젝트 [] 그 크기 myObjects.length의 새로운 객체이어야한다 반환 서명 된 효율적인 유틸리티 메소드를 구현하고 싶습니다 - elemToRemove.length

+0

:

그러나, 가정 두 배열 Object[] myObjectsObject[] toRemove했다 당신은 myObjects에서 날라 toRemove의 요소와 새로운 배열을 반환하는 기능이 필요하다고 당신이 위에있는 것처럼 보이기 때문에, 왜 그 요소들의 색인을 참조하고 그들을 무효로하지 않는가? 배열의 크기를 조정하거나 간단히 요소를 제거 하시겠습니까? – Kaili

+0

가능한 복제본 [Java의 배열에서 객체를 제거하려면 어떻게합니까?] (http://stackoverflow.com/questions/112503/how-do-i-remove-objects-from-an-array-in-java) – McDowell

답변

2

배열의 크기가 변하지 않으므로 (동일한 배열을 유지하면서 요소를 "제거"할 수 없으므로 어딘가에 구멍이 생기기 때문에) 새 배열을 만들어야합니다. 나는이 제안 :

Object[] nobjs = Arrays.copyOf(myObjects, myObjects.length - elemToRemove.length); 
for (int i = 0, j = 0, k = 0; i < myObjects.length; i ++) { 
    if (j < elemToRemove.length && i == elemToRemove[j]) { 
     j ++; 
    } else { 
     nobjs[k ++] = myObjects[i]; 
    } 
} 

elemToRemove 이미 중복 불가능으로 분류되어 있다고 가정 만 들어있는 소스 배열 내에서 수있는 유효한 인덱스. Arrays.copyOf() 호출은 새 배열의 런타임 유형이 소스 배열의 런타임 유형과 동일한 지 확인하는 용도로만 사용됩니다.

배열에서 데이터를 "제거"하여 새 배열을 만들어야하는 경우 Java 배열이 가장 효율적인 데이터 구조가 아닐 수 있습니다. LinkedList 또는 ArrayList이 더 적절할 수 있습니다.

1

요소를 자주 제거하려는 경우 배열 대신 LinkedList를 사용하는 것이 좋습니다.

그것은 (목록 -> 요소 -> 배열 제거 array-> 연결) 배열을 구현하는 것이 쉽다 그러나 그것은 매우 효율적이지 : 당신은 여전히 ​​작동하려면

내가 (가장 효율적인 방법을 생각한다 옛 배열에만 필요 요소와 새로운 배열을 만드는 것입니다) 배열 :

Object[] filteredObjects = new Object[myObjects.length - elemToRemove.length]; 
int j = 0; 
for (int i = 0; i < myObjects.length; i++) { 
    if (!shouldRemove(i)) { 
     filteredObjects[j++] = myObjects[i]; 
    } 
} 
myObjects = filteredObjects; 

나는 shouldRemove를 보이지 않았다. 나는 elemToRemove 배열 (인덱스는 고유하므로 어떤 경우에도 선호되는 방법) 대신 인덱스 집합을 만들어야한다고 생각합니다. 그런 다음 shouldRemoveelemToRemove.contains(i)으로 변경할 수 있습니다.


는 (나는 그것이 효율적 모르겠어요하지만 나를 위해 우아한 모양) 당신이 구글 컬렉션과 함께 또 하나의 방법을 제안 할 수 있습니다 :

for (int index : elemToRemove) { 
    myObjects[i] = null; 
} 
myObjects = Collections2.filter(Arrays.asList(myObjects), new Predicate<Object>() { 
    @Override 
    public boolean apply(Object obj) { 
     return obj!= null; 
    } 
}).toArray(); 
3

당신은 Java 배열에서 요소를 제거 할 수 없습니다. 할 수있는 일은 다음과 같습니다.

  • 보유하려는 요소가 인 새 배열을 만듭니다.
  • 대신 Collections을 사용하십시오.
1

Java 배열은 변경할 수 없으며 중간에 구멍을 두지 않고 항목을 제거 할 수 없습니다.

먼저 요소의 모든 항목을 제거한 다음 모든 구멍을 채워서 배열을 압축합니다. 이것은 비효율적입니다. 그렇지 않으면 올바른 요소만으로 새로운 배열을 만들 수 있지만 미리 크기를 알아야합니다.

가장 좋은 방법은 객체 제거를 허용하는 것이 좋은 LinkedList을 사용하는 것입니다 어떤 구멍도 생기지 않고 그것들을 제외시킴으로써 그들은 단지 구조에서 사라집니다. 그런 다음 Collection.toArray(..)을 사용하여 새 배열을 가져올 수 있습니다.

0

수정하려는 배열이있는 경우 LinkedList 또는 ArrayList과 같은 다양한 컬렉션 클래스를 사용하는 것이 좋습니다. 일반 배열은 크기를 조정할 수 없기 때문에 단순히 요소를 추가/제거 할 수 없습니다. 당신은 일정한 크기의 배열을 사용하는 경우

public static Object[] remove(Object[] myObjects, Object[] toRemove) 
{ 
    HashSet<Object> tr = new HashSet<Object>(); 
    tr.addAll(Arrays.asList(toRemove)); 
    List<Object> removed = new ArrayList<Object>(); 
    for(Object o : myObjects) 
     if(!tr.contains(o)) 
      removed.add(o); 
    return removed.toArray(); 
}