Пересечение и объединение ArrayLists в Java - PullRequest
118 голосов
/ 12 марта 2011

Есть ли способы сделать это?Я искал, но не мог найти.

Еще один вопрос: мне нужны эти методы, чтобы я мог фильтровать файлы.Некоторые из них являются AND фильтрами, а некоторые - OR фильтрами (как в теории множеств), поэтому мне нужно фильтровать по всем файлам и объединять / пересекать ArrayLists, которые содержат эти файлы.

Должен ли я использоватьдругая структура данных для хранения файлов?Есть ли что-нибудь еще, что могло бы предложить лучшее время выполнения?

Ответы [ 20 ]

2 голосов
/ 09 декабря 2017

Вы можете использовать commons-collection4 CollectionUtils

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]
2 голосов
/ 23 октября 2017

В 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();
}
1 голос
/ 17 апреля 2017

Я также работал над подобной ситуацией и пришел сюда в поисках помощи.Закончилось поиском собственного решения для массивов.ArrayList AbsentDates = new 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 );
        }
1 голос
/ 12 апреля 2015

Если объекты в списке являются хэшируемыми (т.е. имеют приличный hashCode и функцию equals), самый быстрый подход между таблицами ок.size> 20 - создать HashSet для большего из двух списков.

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;
    }
}
0 голосов
/ 20 мая 2019

Пересечение двух списков различных объектов на основе общего ключа - 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());
    }
0 голосов
/ 17 сентября 2018

После тестирования вот мой лучший подход к пересечению.

Более высокая скорость по сравнению с чистым подходом HashSet. HashSet и HashMap ниже имеют аналогичную производительность для массивов с более чем 1 миллионом записей.

Что касается подхода Java 8 Stream, скорость довольно мала для размера массива больше 10 КБ.

Надеюсь, это поможет.

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));
}
0 голосов
/ 07 июня 2017

Сначала я копирую все значения массивов в один массив, затем удаляю дублирующиеся значения в массив.Строка 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]+" ");
    }
}   
}
0 голосов
/ 07 июня 2017

Если число совпадает, чем я проверяю, это происходит в первый раз или нет с помощью «indexOf ()», если число совпадает в первый раз, затем выведите и сохраните в строку, чтобы при следующем совпадении того же числа он не будет печататься, потому что из-за «indexOf ()» условие будет ложным.

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;
                }
           }
       }    
}

}

0 голосов
/ 26 сентября 2016

Окончательное решение:

//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;
}
0 голосов
/ 12 марта 2011

Если бы у вас были данные в наборах, вы могли бы использовать класс Sets в Guava.

...