如何获取大小为 X 的 Java 集并分解为 X/Y 集?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16449644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:58:55  来源:igfitidea点击:

How can I take a Java Set of size X and break into X/Y Sets?

javasethashset

提问by James

I have a Java Set (specifically HashSet). Suppose it has a size of 10k. How can I break it into 5 Sets each of size 2k?

我有一个 Java 集(特别是 HashSet)。假设它的大小为 10k。我怎样才能把它分成 5 套,每套 2k?

回答by user2327870

Guavahas libraries to partition Iterable classes. The Iterablesis a utility class which has static methods to partition Iterable classes. The return value is a Iterable of lists though. The given code shows how to do that.

Guava具有用于划分 Iterable 类的库。该Iterables是具有静态方法来划分可迭代类的实用程序类。返回值是一个 Iterable 列表。给定的代码显示了如何做到这一点。

Set<Integer> myIntSet = new HashSet<Integer>();
// fill the set
Iterable<List<Integer>> lists = Iterables.partition(myIntSet, SIZE_EACH_PARTITION);

回答by wchargin

This method will split the elements of the set so that the first set contains the first 2000, the second contains the next 2000, etc.

此方法将拆分集合的元素,以便第一个集合包含前 2000 个,第二个包含下一个 2000,依此类推。

public static <T> List<Set<T>> split(Set<T> original, int count) {
    // Create a list of sets to return.
    ArrayList<Set<T>> result = new ArrayList<Set<T>>(count);

    // Create an iterator for the original set.
    Iterator<T> it = original.iterator();

    // Calculate the required number of elements for each set.
    int each = original.size() / count;

    // Create each new set.
    for (int i = 0; i < count; i++) {
        HashSet<T> s = new HashSet<T>(original.size() / count + 1);
        result.add(s);
        for (int j = 0; j < each && it.hasNext(); j++) {
            s.add(it.next());
        }
    }
    return result;
}

//As example, in your code...

Set<Integer> originalSet = new HashSet<Integer>();
// [fill the set...]
List<Set<Integer>> splitSets = split(originalSet, 5);
Set<Integer> first = splitSets.get(0); // etc.

回答by Tom

Iterate over the entire set, and add the first 2000 elements to a first new set, the 2nd 2000 elements to the 2nd new set, etc.

迭代整个集合,将前 2000 个元素添加到第一个新集合,将第二个 2000 个元素添加到第二个新集合,依此类推。

回答by mszalbach

If you do not want to write it by your own have a look at guava. The Lists class have a method partition(List, int) to split a list into multiple lists with the specified size. See Guava Lists

如果您不想自己编写,请查看guava。Lists 类有一个方法 partition(List, int) 将一个列表拆分为多个具有指定大小的列表。查看番石榴列表

回答by stefaan dutry

I've written something that does the splitting of the set.

我写了一些东西来分割集合。

It uses intermediate arrays and Lists.

它使用中间数组和列表。

It uses the Arrays.asList and the Arrays.copyOfRange methods.

它使用 Arrays.asList 和 Arrays.copyOfRange 方法。

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;


public class SetSplitTest {
    //define and initialize set
    private static Set<Integer> largeSet;
    static {
        largeSet  = new HashSet<Integer>();

        for (int i = 0; i < 10000; i++) {
            largeSet.add(i);
        }
    }


    public static void main() {
        System.out.println(largeSet);
        int amountOfSets = 5; //amount of subsets wanted
        Set<Integer>[] subsets = new Set[amountOfSets]; //array holding the subsets

        Integer[] largesetarray =  largeSet.toArray(new Integer[largeSet.size()]);

        for (int i = 1; i <= amountOfSets; i++) {
            int fromIndex = (i-1) * largeSet.size() / amountOfSets;
            int toIndex = i * largeSet.size() / amountOfSets - 1; 
            Set<Integer> subHashSet = new HashSet<Integer>();
            subHashSet.addAll(Arrays.asList(Arrays.copyOfRange(largesetarray, fromIndex, toIndex)));

            subsets[i - 1] = subHashSet;
        }

        for (Set<Integer> subset : subsets) {
            System.out.println(subset);
        }
    }
}

This definately not the most elegant solution, but it's the best i could think off at the moment when not wanting to loop the sets yourself.

这绝对不是最优雅的解决方案,但这是我现在不想自己循环设置时能想到的最好的解决方案。