sourcecode

Java에서의 Array Lists의 교차로 및 결합

copyscript 2022. 8. 9. 22:55
반응형

Java에서의 Array Lists의 교차로 및 결합

그렇게 할 수 있는 방법이 있나요?찾고 있었는데 하나도 안 나왔어요.

다른 질문 합니다.파일을 필터링하려면 이 방법이 필요합니다.「 」라고 하는 것도 .AND 및 필터는 '필터'입니다.OR필터(세트 이론과 같음)는 모든 파일과 이러한 파일을 보관하고 있는 unity/intersects ArrayLists에 따라 필터링해야 합니다.

파일을 보관하기 위해 다른 데이터 구조를 사용해야 합니까?더 나은 실행 시간을 제공할 수 있는 다른 방법이 있습니까?

다음은 서드파티 라이브러리를 사용하지 않는 단순한 구현입니다.★★★에 대한 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;
    }
}

컬렉션(즉 Array List)에는 다음과 같은 기능이 있습니다.

col.retainAll(otherCol) // for intersection
col.addAll(otherCol) // for union

반복을 허용하면 목록 구현을 사용하고, 허용하지 않으면 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]

이 게시물은 꽤 오래되었지만, 그럼에도 불구하고 그 주제를 찾았을 때 구글에 뜬 것은 처음이었다.

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.

자세한 내용은 컬렉션 매뉴얼(ArrayList는 컬렉션) http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html을 참조하십시오.

조합 및 교차로는 목록이 아닌 집합에 대해서만 정의됩니다.말씀하신대로.

guava 라이브러리에서 필터를 확인합니다.또한 guava는 실제 교차로와 결합을 제공합니다.

 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 + n)의 복잡도로 O(n log n + n)에 있습니다.그 결합은 비슷한 방식으로 행해진다.if-else-else 스테이트먼트를 적절히 수정해 주세요.

필요에 따라 반복기를 사용할 수도 있습니다(C++에서 더 효율적이라는 것을 알고 있습니다.Java에서도 마찬가지인지는 모르겠습니다).

는 가 이 말을 해.Set파일을 보관하려면 파일을 보관해야 합니다.그런 다음 Guava의 Sets 클래스를 사용하여union,intersection「」에 Predicate뿐만 아니라.이 방법들과 다른 제안들의 차이점은 이 모든 방법들이 두 집합의 합집합, 교차점 등에 대한 게으른 뷰를 만든다는 것이다.Apache Commons는 새 컬렉션을 만들고 여기에 데이터를 복사합니다. retainAll컬렉션에서 요소를 제거하여 컬렉션 중 하나를 변경합니다.

다음으로 스트림과의 교차를 실시하는 방법을 나타냅니다(스트림에는 Java 8을 사용해야 합니다).

List<foo> fooList1 = new ArrayList<>(Arrays.asList(new foo(), new foo()));
List<foo> fooList2 = new ArrayList<>(Arrays.asList(new foo(), new foo()));
fooList1.stream().filter(f -> fooList2.contains(f)).collect(Collectors.toList());

유형이 다른 목록의 예제입니다.foo와 bar 사이에 실체가 있고 foo에서 stream을 변경할 수 있는 것보다 bar-object를 얻을 수 있는 경우:

List<foo> fooList = new ArrayList<>(Arrays.asList(new foo(), new foo()));
List<bar> barList = new ArrayList<>(Arrays.asList(new bar(), new bar()));

fooList.stream().filter(f -> barList.contains(f.getBar()).collect(Collectors.toList());

commons-collections4 Collection Utils를 사용할 수 있습니다.

Collection<Integer> collection1 = Arrays.asList(1, 2, 4, 5, 7, 8);
Collection<Integer> collection2 = Arrays.asList(2, 3, 4, 6, 8);

Collection<Integer> intersection = CollectionUtils.intersection(collection1, collection2);
System.out.println(intersection); // [2, 4, 8]

Collection<Integer> union = CollectionUtils.union(collection1, collection2);
System.out.println(union); // [1, 2, 3, 4, 5, 6, 7, 8]

Collection<Integer> subtract = CollectionUtils.subtract(collection1, collection2);
System.out.println(subtract); // [1, 5, 7]
  • retainAll은 목록을 수정합니다.
  • Guava에는 목록에 대한 API가 없습니다(세트 전용).

List Utils는 이 사용 사례에 매우 도움이 되었습니다.

기존 목록을 수정하지 않으려면 org.apache.commons.collections의 ListUtils를 사용합니다.

ListUtils.intersection(list1, list2)

Java 8에서는 다음과 같은 간단한 도우미 방법을 사용합니다.

public static <T> Collection<T> getIntersection(Collection<T> coll1, Collection<T> coll2){
    return Stream.concat(coll1.stream(), coll2.stream())
            .filter(coll1::contains)
            .filter(coll2::contains)
            .collect(Collectors.toSet());
}

public static <T> Collection<T> getMinus(Collection<T> coll1, Collection<T> coll2){
    return coll1.stream().filter(not(coll2::contains)).collect(Collectors.toSet());
}

public static <T> Predicate<T> not(Predicate<T> t) {
    return t.negate();
}

Java 8 이후 한 줄

static java.syslog.stream을 Import합니다.Stream.concat;
static java.syslog.stream을 Import합니다.Collectors.toList;
static java.syslog.stream을 Import합니다.Collectors. to 세트;

중복이 없는 경우 결합:

  return concat(a.stream(), b.stream()).collect(toList());

조합 및 구별:

  return concat(a.stream(), b.stream()).distinct().collect(toList());

컬렉션/세트 반환 유형:

  return concat(a.stream(), b.stream()).collect(toSet());

중복되지 않는 경우 교차:

  return a.stream().filter(b::contains).collect(toList());

collection If 。b는 O(1)가큰이므로 O(1) 앞에 합니다.returnHasSet (import java.util.Set; ):

... b = Set.copyOf(b);

교차 및 구별:

  return a.stream().distinct().filter(b::contains).collect(toList());

목록 내의 오브젝트가 해시 가능한 경우(즉, 적절한 해시 코드와 등가함수), 테이블 사이즈가 약 20 이상인 경우 가장 빠른 접근법은 두 목록 중 더 큰 목록에 대해 해시 세트를 구축하는 것입니다.

public static <T> ArrayList<T> intersection(Collection<T> a, Collection<T> b) {
    if (b.size() > a.size()) {
        return intersection(b, a);
    } else {
        if (b.size() > 20 && !(a instanceof HashSet)) {
            a = new HashSet(a);
        }
        ArrayList<T> result = new ArrayList();
        for (T objb : b) {
            if (a.contains(objb)) {
                result.add(objb);
            }
        }
        return result;
    }
}

저도 비슷한 상황에 대처하고 있었는데 도움을 요청하러 왔습니다.어레이 전용 솔루션을 찾게 되었습니다.ArrayList AbsentDates = 새 ArrayList(); // Array1-Array2를 저장합니다.

주의: 이 페이지에 접속하는 사람에게 도움이 될 수 있는 경우는, 투고해 주세요.

ArrayList<String> AbsentDates = new ArrayList<String>();//This Array will store difference
      public void AbsentDays() {
            findDates("April", "2017");//Array one with dates in Month April 2017
            findPresentDays();//Array two carrying some dates which are subset of Dates in Month April 2017

            for (int i = 0; i < Dates.size(); i++) {

                for (int j = 0; j < PresentDates.size(); j++) {

                    if (Dates.get(i).equals(PresentDates.get(j))) {

                        Dates.remove(i);
                    }               

                }              
                AbsentDates = Dates;   
            }
            System.out.println(AbsentDates );
        }

공통 키에 기반한 서로 다른 오브젝트 목록 2개의 교차점 - Java 8

 private List<User> intersection(List<User> users, List<OtherUser> list) {

        return list.stream()
                .flatMap(OtherUser -> users.stream()
                        .filter(user -> user.getId()
                                .equalsIgnoreCase(OtherUser.getId())))
                .collect(Collectors.toList());
    }
public static <T> Set<T> intersectCollections(Collection<T> col1, Collection<T> col2) {
    Set<T> set1, set2;
    if (col1 instanceof Set) {
        set1 = (Set) col1;
    } else {
        set1 = new HashSet<>(col1);
    }

    if (col2 instanceof Set) {
        set2 = (Set) col2;
    } else {
        set2 = new HashSet<>(col2);
    }

    Set<T> intersection = new HashSet<>(Math.min(set1.size(), set2.size()));

    for (T t : set1) {
        if (set2.contains(t)) {
            intersection.add(t);
        }
    }

    return intersection;
}

JDK8+ (아마도 최고의 퍼포먼스)

public static <T> Set<T> intersectCollections(Collection<T> col1, Collection<T> col2) {
    boolean isCol1Larger = col1.size() > col2.size();
    Set<T> largerSet;
    Collection<T> smallerCol;

    if (isCol1Larger) {
        if (col1 instanceof Set) {
            largerSet = (Set<T>) col1;
        } else {
            largerSet = new HashSet<>(col1);
        }
        smallerCol = col2;
    } else {
        if (col2 instanceof Set) {
            largerSet = (Set<T>) col2;
        } else {
            largerSet = new HashSet<>(col2);
        }
        smallerCol = col1;
    }

    return smallerCol.stream()
            .filter(largerSet::contains)
            .collect(Collectors.toSet());
}

퍼포먼스를 중시하지 않고, 작은 코드를 원하는 경우는, 다음의 조작을 실시해 주세요.

col1.stream().filter(col2::contains).collect(Collectors.toList());

먼저 어레이의 모든 값을 단일 어레이에 복사하고 다음으로 중복된 값을 어레이에 제거합니다.12행은 같은 숫자가 시간보다 많이 발생할 경우 가비지 값을 "j" 위치에 추가한다고 설명합니다.마지막으로 시작 끝에서 이동하여 동일한 가비지 값이 발생하는지 확인한 후 폐기합니다.

public class Union {
public static void main(String[] args){

    int arr1[]={1,3,3,2,4,2,3,3,5,2,1,99};
    int arr2[]={1,3,2,1,3,2,4,6,3,4};
    int arr3[]=new int[arr1.length+arr2.length];

    for(int i=0;i<arr1.length;i++)
        arr3[i]=arr1[i];

    for(int i=0;i<arr2.length;i++)
        arr3[arr1.length+i]=arr2[i];
    System.out.println(Arrays.toString(arr3));

    for(int i=0;i<arr3.length;i++)
    {
        for(int j=i+1;j<arr3.length;j++)
        {
            if(arr3[i]==arr3[j])
                arr3[j]=99999999;          //line  12
        }
    }
    for(int i=0;i<arr3.length;i++)
    {
        if(arr3[i]!=99999999)
            System.out.print(arr3[i]+" ");
    }
}   
}

테스트 후 최적의 교차로 접근법은 다음과 같습니다.

순수 HashSet 접근법에 비해 속도가 빠릅니다.아래의 HashSet과 HashMap은 100만 개 이상의 레코드를 가진 어레이에서도 동일한 성능을 발휘합니다.

Java 8 Stream 접근법의 경우 어레이 크기가 10k를 초과할 경우 속도가 상당히 느립니다.

이게 도움이 되길 바라.

public static List<String> hashMapIntersection(List<String> target, List<String> support) {
    List<String> r = new ArrayList<String>();
    Map<String, Integer> map = new HashMap<String, Integer>();
    for (String s : support) {
        map.put(s, 0);
    }
    for (String s : target) {
        if (map.containsKey(s)) {
            r.add(s);
        }
    }
    return r;
}
public static List<String> hashSetIntersection(List<String> a, List<String> b) {
    Long start = System.currentTimeMillis();

    List<String> r = new ArrayList<String>();
    Set<String> set = new HashSet<String>(b);

    for (String s : a) {
        if (set.contains(s)) {
            r.add(s);
        }
    }
    print("intersection:" + r.size() + "-" + String.valueOf(System.currentTimeMillis() - start));
    return r;
}

public static void union(List<String> a, List<String> b) {
    Long start = System.currentTimeMillis();
    Set<String> r= new HashSet<String>(a);
    r.addAll(b);
    print("union:" + r.size() + "-" + String.valueOf(System.currentTimeMillis() - start));
}

retainAll() 메서드를 사용하여 공통 요소를 찾습니다.즉, intersection list1.retainAll(list2)

다음 방법을 사용할 수 있습니다.

CollectionUtils.containsAny그리고.CollectionUtils.containsAll

Apache Commons에서.

최종 솔루션:

//all sorted items from both
public <T> List<T> getListReunion(List<T> list1, List<T> list2) {
    Set<T> set = new HashSet<T>();
    set.addAll(list1);
    set.addAll(list2);
    return new ArrayList<T>(set);
}

//common items from both
public <T> List<T> getListIntersection(List<T> list1, List<T> list2) {
    list1.retainAll(list2);
    return list1;
}

//common items from list1 not present in list2
public <T> List<T> getListDifference(List<T> list1, List<T> list2) {
    list1.removeAll(list2);
    return list1;
}

세트에 데이터가 있는 경우 Guava 클래스를 사용할 수 있습니다.

처음에 확인한 수치보다 일치하는 경우 또는 "index Of()"의 도움을 받아 번호가 일치하는지 여부를 확인하고 있지 않은 경우 다음 번에 같은 번호가 일치할 때 "index Of()" 조건이 false이기 때문에 인쇄되지 않도록 문자열에 저장하십시오.

class Intersection
{
public static void main(String[] args)
 {
  String s="";
    int[] array1 = {1, 2, 5, 5, 8, 9, 7,2,3512451,4,4,5 ,10};
    int[] array2 = {1, 0, 6, 15, 6, 5,4, 1,7, 0,5,4,5,2,3,8,5,3512451};


       for (int i = 0; i < array1.length; i++)
       {
           for (int j = 0; j < array2.length; j++)
           {
               char c=(char)(array1[i]);
               if(array1[i] == (array2[j])&&s.indexOf(c)==-1)
               {    
                System.out.println("Common element is : "+(array1[i]));
                s+=c;
                }
           }
       }    
}

}

언급URL : https://stackoverflow.com/questions/5283047/intersection-and-union-of-arraylists-in-java

반응형