【问题标题】:How can I take a Java Set of size X and break into X/Y Sets?如何获取大小为 X 的 Java 集并分解为 X/Y 集?
【发布时间】:2013-05-08 20:29:55
【问题描述】:

我有一个 Java 集(特别是 HashSet)。假设它的大小为 10k。如何将其分成 5 组,每组 2k 大小?

【问题讨论】:

  • 在将元素分配到这 5 个子集中时,是否有一些特定的规则需要使用?
  • @Pshemo:不需要特定的规则。我可以按照 nhahtdh 的建议去做。我以为我只是忽略了像 List.subList 之类的 lib 调用
  • @James 这就是 JavaDoc 的用途:ListCollectionsArraysSet...

标签: java set hashset


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    此方法将拆分集合的元素,以便第一个集合包含前 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.
    

    【讨论】:

    • j.add(it.next()) => s.add(it.next());我想是的
    • 如果将 5 个元素划分为具有 2 个元素的页面,您的代码会给出 2 个具有 2 个元素的页面。最后一个丢了。因此i &lt; count => i &lt;= count
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      它使用中间数组和列表。

      它使用 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);
              }
          }
      }
      

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

      【讨论】:

        【解决方案5】:

        遍历整个集合,并将前 2000 个元素添加到第一个新集合中,将第二个 2000 个元素添加到第二个新集合中,等等。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-02-03
          • 1970-01-01
          • 1970-01-01
          • 2011-06-11
          • 2023-01-13
          • 1970-01-01
          • 1970-01-01
          • 2020-10-08
          相关资源
          最近更新 更多