Java中ArrayList的交集和并集

发布于 2024-10-21 07:12:15 字数 189 浏览 5 评论 0 原文

有什么方法可以做到这一点吗?我正在寻找,但没有找到。

另一个问题:我需要这些方法,以便我可以过滤文件。 有些是 AND 过滤器,有些是 OR 过滤器(就像在集合论中一样),所以我需要根据所有文件和保存这些文件的联合/相交 ArrayList 进行过滤。

我应该使用不同的数据结构来保存文件吗?还有其他什么可以提供更好的运行时间吗?

Are there any methods to do so? I was looking but couldn't find any.

Another question: I need these methods so I can filter files.
Some are AND filters and some are OR filters (like in set theory), so I need to filter according to all files and the unite/intersects ArrayLists that holds those files.

Should I use a different data structure to hold the files? Is there anything else that would offer a better runtime?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(24

你在看孤独的风景 2024-10-28 07:12:15

这是一个不使用任何第三方库的简单实现。相对于 retainAllremoveAlladdAll 的主要优点是这些方法不会修改方法的原始列表输入。

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

Here's a plain implementation without using any third-party library. Main advantage over retainAll, removeAll and addAll is that these methods don't modify the original lists input to the methods.

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;
    }
}
虐人心 2024-10-28 07:12:15

Collection (所以 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]

Collection (so ArrayList also) have:

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

Use a List implementation if you accept repetitions, a Set implementation if you don't:

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]
晒暮凉 2024-10-28 07:12:15

这篇文章相当老了,但它是在谷歌搜索该主题时第一个出现的文章。

我想使用 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());

如果有人有更好/更快的解决方案,请告诉我,但这个解决方案是一个很好的单行代码,可以轻松包含在方法中无需添加不必要的帮助类/方法,并且仍然保持可读性。

This post is fairly old, but nevertheless it was the first one popping up on google when looking for that topic.

I want to give an update using Java 8 streams doing (basically) the same thing in a single line:

List<T> intersect = list1.stream()
    .filter(list2::contains)
    .collect(Collectors.toList());

List<T> union = Stream.concat(list1.stream(), list2.stream())
    .distinct()
    .collect(Collectors.toList());

If anyone has a better/faster solution let me know, but this solution is a nice one liner that can be easily included in a method without adding a unnecessary helper class/method and still keep the readability.

叫思念不要吵 2024-10-28 07:12:15
list1.retainAll(list2) - is intersection

union 将先是 removeAll,然后是 addAll

更多内容请参见collection的文档(ArrayList是一个集合)
http://download.oracle.com/javase /1.5.0/docs/api/java/util/Collection.html

list1.retainAll(list2) - is intersection

union will be removeAll and then addAll.

Find more in the documentation of collection(ArrayList is a collection)
http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html

坏尐絯 2024-10-28 07:12:15

并集和交集仅为集合而不是列表定义。正如你提到的。

检查 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)

Unions and intersections defined only for sets, not lists. As you mentioned.

Check guava library for filters. Also guava provides real intersections and unions

 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)
薄情伤 2024-10-28 07:12:15

您可以使用 apache 公共资源

// list1 = [1, 2, 3, 4, 5]
// list2 = [3, 4, 5, 6, 7]

HashSet<String> union = CollectionUtils.union(list1, list2); 
// creates and returns a new set that contains all (unique) elements in both lists
// in this case, union = [1, 2, 3, 4, 5, 6, 7]

HashSet<String> intersect = CollectionUtils.intersection(list1, list2);
// creates and returns a new set that contains all elements that are in both of the lists
// in this case, intersect = [3, 4, 5]

这两种方法还具有数组和映射的重载,并将 null 输入视为空集。由于它们返回集合,因此它们保留顺序。

You can use CollectionUtils from apache commons.

// list1 = [1, 2, 3, 4, 5]
// list2 = [3, 4, 5, 6, 7]

HashSet<String> union = CollectionUtils.union(list1, list2); 
// creates and returns a new set that contains all (unique) elements in both lists
// in this case, union = [1, 2, 3, 4, 5, 6, 7]

HashSet<String> intersect = CollectionUtils.intersection(list1, list2);
// creates and returns a new set that contains all elements that are in both of the lists
// in this case, intersect = [3, 4, 5]

Both of these methods also have overloads for arrays and maps, and treat null inputs as an empty set. Since they return sets, they do not preserve order.

东风软 2024-10-28 07:12:15

标记的解决方案效率不高。它的时间复杂度为 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)。
联盟以类似的方式完成。只需确保对 if-elseif-else 语句进行适当的修改即可。

如果需要,您也可以使用迭代器(我知道它们在 C++ 中效率更高,我不知道在 Java 中是否也是如此)。

The solution marked is not efficient. It has a O(n^2) time complexity. What we can do is to sort both lists, and the execute an intersection algorithm as the one below.

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

This one has a complexity of O(n log n + n) which is in O(n log n).
The union is done in a similar manner. Just make sure you make the suitable modifications on the if-elseif-else statements.

You can also use iterators if you want (I know they are more efficient in C++, I dont know if this is true in Java as well).

不可一世的女人 2024-10-28 07:12:15

JAVA 8以来的单行代码

联合

如果没有重复项则

  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());

性能:如果集合b 很大并且不是 O(1),然后通过在 return 之前添加 1 行来预先优化过滤器性能:复制到 HasSet (导入 java.util.Set;):

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

相交和不同:

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

- 导入

导入静态java.util.stream.Stream.concat;
导入静态 java.util.stream.Collectors.toList;
导入静态java.util.stream.Collectors.toSet;

One-liners since JAVA 8

Union

if there are no duplicates:

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

union and distinct:

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

union and distinct if Collection/Set return type:

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

Intersect

if no duplicates:

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

PERFORMANCE: If collection b is huge and not O(1), then pre-optimize the filter performance by adding 1 line before return: Copy to HasSet (import java.util.Set;):

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

intersect and distinct:

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

- imports

import static java.util.stream.Stream.concat;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;

回忆那么伤 2024-10-28 07:12:15

我认为如果你想对文件进行交集和并集,你应该使用 Set 来保存文件。然后您可以使用 Guava设置类来执行并集交集 并通过 Predicate 进行过滤。这些方法与其他建议之间的区别在于,所有这些方法都会创建两个集合的并集、交集等的惰性视图。 Apache Commons 创建一个新集合并将数据复制到其中。 retainAll 通过删除其中的元素来更改您的集合之一。

I think you should use a Set to hold the files if you want to do intersection and union on them. Then you can use Guava's Sets class to do union, intersection and filtering by a Predicate as well. The difference between these methods and the other suggestions is that all of these methods create lazy views of the union, intersection, etc. of the two sets. Apache Commons creates a new collection and copies data to it. retainAll changes one of your collections by removing elements from it.

左秋 2024-10-28 07:12:15

这是一种与流进行交集的方法(请记住,您必须对流使用 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 获取 bar 对象,那么您可以修改流:

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());

Here is a way how you can do an intersection with streams (remember that you have to use java 8 for streams):

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());

An example for lists with different types. If you have a realtion between foo and bar and you can get a bar-object from foo than you can modify your stream:

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());
聽兲甴掵 2024-10-28 07:12:15

您可以使用 commons-collections4 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]

You can use commons-collections4 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]
梦一生花开无言 2024-10-28 07:12:15
  • keepAll 将修改你的列表
  • Guava 没有 List 的 API(仅适用于 set)

我发现 ListUtils 对于这个用例非常有用。

如果您不想修改现有列表,请使用 org.apache.commons.collections 中的 ListUtils。

ListUtils.intersection(list1, list2)

  • retainAll will modify your list
  • Guava doesn't have APIs for List (only for set)

I found ListUtils very useful for this use case.

Use ListUtils from org.apache.commons.collections if you do not want to modify existing list.

ListUtils.intersection(list1, list2)

少女情怀诗 2024-10-28 07:12:15

在 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();
}

In Java 8, I use simple helper methods like this:

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();
}
跨年 2024-10-28 07:12:15

如果列表中的对象是可散列的(即具有合适的 hashCode 和 equals 函数),则表之间最快的方法大约是。尺寸> 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;
    }
}

If the objects in the list are hashable (i.e. have a decent hashCode and equals function), the fastest approach between tables approx. size > 20 is to construct a HashSet for the larger of the two lists.

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;
    }
}
无人接听 2024-10-28 07:12:15

我也在处理类似的情况并到达这里寻求帮助。最终找到了我自己的数组解决方案。
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 );
        }

I was also working on the similar situation and reached here searching for help. Ended up finding my own solution for Arrays.
ArrayList AbsentDates = new ArrayList(); // Will Store Array1-Array2

Note : Posting this if it can help someone reaching this page for help.

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 );
        }
蓝梦月影 2024-10-28 07:12:15

基于公共键的不同对象的两个列表的交集 - 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());
    }

Intersection of two list of different object based on common key - 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());
    }
黯淡〆 2024-10-28 07:12:15
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());
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+ (Probably Best Performance)

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

If you don't care about performance and prefer smaller code just use:

col1.stream().filter(col2::contains).collect(Collectors.toList());
相思故 2024-10-28 07:12:15

keepAll() 方法用于查找公共元素..即;交集
列表1.retainAll(列表2)

retainAll() method use for finding common element..i.e;intersection
list1.retainAll(list2)

初心 2024-10-28 07:12:15

首先,我将数组的所有值复制到一个数组中,然后将重复值删除到数组中。第 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]+" ");
    }
}   
}

First, I am copying all values of arrays into a single array then I am removing duplicates values into the array. Line 12, explaining if same number occur more than time then put some extra garbage value into "j" position. At the end, traverse from start-end and check if same garbage value occur then discard.

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]+" ");
    }
}   
}
如梦亦如幻 2024-10-28 07:12:15

经过测试,这是我最好的交叉方法。

与纯 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));
}

After testing, here is my best intersection approach.

Faster speed compared to pure HashSet Approach. HashSet and HashMap below has similar performance for arrays with more than 1 million records.

As for Java 8 Stream approach, speed is quite slow for array size larger then 10k.

Hope this can help.

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));
}
乖乖兔^ω^ 2024-10-28 07:12:15

您可以使用以下方法:

CollectionUtils.containsAny 和 CollectionUtils.containsAll

Apache Commons

You can use the methods:

CollectionUtils.containsAny and CollectionUtils.containsAll

from Apache Commons.

咽泪装欢 2024-10-28 07:12:15

最终解决方案:

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

Final solution:

//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;
}
夜吻♂芭芘 2024-10-28 07:12:15

如果您的数据集中在 Sets 中,则可以使用 Guava 的 设置类。

If you had your data in Sets you could use Guava's Sets class.

我三岁 2024-10-28 07:12:15

如果数字与我正在检查的数字匹配,则在“indexOf()”的帮助下,它是第一次发生,如果数字第一次匹配,则打印并保存到字符串中,这样,当下次相同的数字匹配时,它就赢了。 t 打印,因为由于“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;
                }
           }
       }    
}

}

If the number matches than I am checking it's occur first time or not with help of "indexOf()" if the number matches first time then print and save into in a string so, that when the next time same number matches then it's won't print because due to "indexOf()" condition will be 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;
                }
           }
       }    
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文