그렇게하는 방법이 있습니까? 찾고 있었지만 찾을 수 없었습니다.
또 다른 질문 : 파일을 필터링 할 수 있도록 이러한 방법이 필요합니다. 일부는 AND
필터이고 일부는 OR
(이론과 같은) 필터이므로 모든 파일에 따라 필터링해야하며 해당 파일을 보유하는 Unite / intersects ArrayList를 필터링해야합니다.
파일을 보유하기 위해 다른 데이터 구조를 사용해야합니까? 더 나은 런타임을 제공하는 다른 것이 있습니까?
답변
다음은 타사 라이브러리를 사용하지 않는 일반 구현입니다. 주요 장점을 통해 retainAll
, removeAll
그리고 addAll
이러한 방법은 방법 원래 목록 입력을 수정하지 않는 것이 있습니다.
public class Test {
public static void main(String... args) throws Exception {
List<String> list1 = new ArrayList<String>(Arrays.asList("A", "B", "C"));
List<String> list2 = new ArrayList<String>(Arrays.asList("B", "C", "D", "E", "F"));
System.out.println(new Test().intersection(list1, list2));
System.out.println(new Test().union(list1, list2));
}
public <T> List<T> union(List<T> list1, List<T> list2) {
Set<T> set = new HashSet<T>();
set.addAll(list1);
set.addAll(list2);
return new ArrayList<T>(set);
}
public <T> List<T> intersection(List<T> list1, List<T> list2) {
List<T> list = new ArrayList<T>();
for (T t : list1) {
if(list2.contains(t)) {
list.add(t);
}
}
return list;
}
}
답변
컬렉션 (따라서 ArrayList도)은 다음과 같습니다.
col.retainAll(otherCol) // for intersection
col.addAll(otherCol) // for union
반복을 수락하면 List 구현을 사용하고, 그렇지 않으면 Set 구현을 사용하십시오.
Collection<String> col1 = new ArrayList<String>(); // {a, b, c}
// Collection<String> col1 = new TreeSet<String>();
col1.add("a");
col1.add("b");
col1.add("c");
Collection<String> col2 = new ArrayList<String>(); // {b, c, d, e}
// Collection<String> col2 = new TreeSet<String>();
col2.add("b");
col2.add("c");
col2.add("d");
col2.add("e");
col1.addAll(col2);
System.out.println(col1);
//output for ArrayList: [a, b, c, b, c, d, e]
//output for TreeSet: [a, b, c, d, e]
답변
이 게시물은 상당히 오래되었지만 그럼에도 불구하고 해당 주제를 찾을 때 Google에 처음 나타나는 게시물입니다.
Java 8 스트림을 사용하여 한 줄에 (기본적으로) 동일한 작업을 수행하여 업데이트를 제공하고 싶습니다.
List<T> intersect = list1.stream()
.filter(list2::contains)
.collect(Collectors.toList());
List<T> union = Stream.concat(list1.stream(), list2.stream())
.distinct()
.collect(Collectors.toList());
누구든지 더 나은 / 빠른 솔루션을 가지고 있다면 알려주세요. 그러나이 솔루션은 불필요한 도우미 클래스 / 메소드를 추가하지 않고 메소드에 쉽게 포함시킬 수 있고 여전히 가독성을 유지하는 좋은 라이너입니다.
답변
list1.retainAll(list2) - is intersection
노동 조합이 될 것입니다 removeAll
다음과addAll
.
collection (ArrayList is collection) 문서에서 자세한 내용을 확인
하십시오. http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html
답변
합집합과 교집합은 목록이 아닌 세트에 대해서만 정의됩니다. 당신이 언급했듯이.
필터는 구아바 라이브러리를 확인하십시오 . 또한 구아바는 실제 교차로와 노조를 제공합니다
static <E> Sets.SetView<E >union(Set<? extends E> set1, Set<? extends E> set2)
static <E> Sets.SetView<E> intersection(Set<E> set1, Set<?> set2)
답변
당신은 아파치 커먼즈CollectionUtils
에서 사용할 수 있습니다 .
답변
표시된 솔루션이 효율적이지 않습니다. 시간 복잡도는 O (n ^ 2)입니다. 우리가 할 수있는 일은 두 목록을 정렬하고 아래와 같이 교차 알고리즘을 실행하는 것입니다.
private static ArrayList<Integer> interesect(ArrayList<Integer> f, ArrayList<Integer> s) {
ArrayList<Integer> res = new ArrayList<Integer>();
int i = 0, j = 0;
while (i != f.size() && j != s.size()) {
if (f.get(i) < s.get(j)) {
i ++;
} else if (f.get(i) > s.get(j)) {
j ++;
} else {
res.add(f.get(i));
i ++; j ++;
}
}
return res;
}
이것은 O (n log n)에있는 O (n log n + n)의 복잡성을가집니다. 노조도 비슷한 방식으로 이루어집니다. if-elseif-else 문을 적절히 수정하십시오.
원하는 경우 반복자를 사용할 수도 있습니다 (C ++에서 더 효율적이라는 것을 알고 있습니다 .Java에서도 이것이 사실인지 모르겠습니다).