【问题标题】:Re arrange Java list based on a sub list根据子列表重新排列 Java 列表
【发布时间】:2021-06-06 08:00:56
【问题描述】:

我有一个要求,我需要重新排列列表中的数字。 假设我有一个大小为 N 的整数列表。然后根据输入网格大小,我对列表进行分区并创建分区映射。例如下面的代码将创建一个分区图。

public static Map<String, Map<String, Integer>> partition(List<Integer> list, int gridSize) {
        int size = list.size() - 1;
        int targetSize = size / gridSize + 1;

        Map<String, Map<String, Integer>> result = new HashMap<String, Map<String, Integer>>();
        int number = 0;
        int start = 0;
        int end = start + targetSize - 1;

        while (start <= size) {
            Map<String, Integer> value = new HashMap<String, Integer>();
            result.put("partition" + number, value);

            if (end >= size ) {
                end = size;
            }
            value.put("startIndex", ids.get(start));
            value.put("endIndex", ids.get(end));
            start += targetSize;
            end += targetSize;
            number++;
        }
        
        return result;
    }

对于包含 100 个从 1 到 100 且 gridSize 为 12 的整数的列表,上述代码将生成以下分区。

partition0={startIndex=1, endIndex=9}, partition1={startIndex=10, endIndex=18}, partition2={startIndex=19, endIndex=27}, partition3={startIndex=28, endIndex=36}, partition4={startIndex=37, endIndex=45}, partition5={startIndex=46, endIndex=54}, partition6={startIndex=55, endIndex=63}, partition7={startIndex=64, endIndex=72}, partition8={startIndex=73, endIndex=81}, partition9={startIndex=82, endIndex=90}, partition10={startIndex=91, endIndex=99}, partition11={startIndex=100, endIndex=100}}
{partition0={startIndex=1, endIndex=9}, partition1={startIndex=10, endIndex=18}, partition2={startIndex=19, endIndex=27}, partition3={startIndex=28, endIndex=36}, partition4={startIndex=37, endIndex=45}, partition5={startIndex=46, endIndex=54}, partition6={startIndex=55, endIndex=63}, partition7={startIndex=64, endIndex=72}, partition8={startIndex=73, endIndex=81}, partition9={startIndex=82, endIndex=90}, partition10={startIndex=91, endIndex=99}, partition11={startIndex=100, endIndex=100}

现在我有另一个列表,它是我在上面分区的列表的子集。

例如要分区的原始列表:

[1, 2, 3, ..... ,98, 99, 100]

以上列表的子集:

[3, 4, 5, 6, 7, 11, 12, 14, 15, 16, 17, 21, 26, 28, 33, 38, 42, 67, 74, 82, 84, 91, 92]

我想根据子集列表重新排列第一个列表中的元素,以便子集列表中的元素是 均匀分布在从第一个列表生成的分区中。第一个列表中的元素将保持不变 但它们将根据子集列表重新排列。基本上我会先重新排列列表,然后再创建分区。

在上面的示例中,子集列表有 23 个元素。对于 12 的 gridSize,子集列表中的 23 个元素应该 分布在 12 个分区中,因此在这种情况下,每个分区应该有来自子集列表的 2 个元素。

这个问题与spring批处理分区有关。 列表中的整数实际上是 Spring Batch 处理器要处理的用户 ID。一些用户需要更多时间来处理 相对于其它的。因此,在分区期间可能发生的情况是,某些分区可能包含更多的用户,这些用户比其他分区花费更多的处理时间。 这会导致某些分区/线程在其他分区之前完成并且未使用,从而延迟作业完成。 子集列表是需要更多处理时间的用户列表。我想将这些用户均匀地分布在不同的分区中。

【问题讨论】:

  • 您是否还可以添加您想要摆脱的重新排列的列表?我想您希望子集列表元素成为起始列表的一部分,但在生成的分区之间均匀分布,对吧?
  • @Filip 是的,你是对的。我将尝试分享结果重新排列的列表。

标签: java list arraylist


【解决方案1】:

我假设您不能更改分区功能,只能更改输入列表顺序。如果不是这种情况,还有更好的解决方案。 我还假设列表中没有重复项。

如果子集超过所有值的一半,则此解决方案将不起作用。

//list_all = Arrays.asList(1, 2, ..., 100)
//list_sub = Arrays.asList(4, 6, 55)

public static List<Integer> reorder(List<Integer> all, List<Integer> sub) {
  all.removeAll(sub);
  int every = all.size() / sub.size();
  List<Integer> result = new ArrayList();
  Iterator<Integer> sub_it = sub.iterator();
  for(int i=0; i<all.size(); i++) {
     result.add(all.get(i));
     if(i%every == 0 && sub_it.hasNext())
       result.add(sub_it.next());
  }

  while(sub_it.hasNext())
    result.add(sub_it.next());
  
  return result;
}

对不起,代码有错误,我写的很匆忙。

【讨论】:

  • 输入列表和子集列表中没有重复项。但是子集列表可能超过所有值的一半。如果分区数始终等于输入网格大小,我可以更改分区逻辑。
猜你喜欢
  • 1970-01-01
  • 2021-05-19
  • 2015-02-27
  • 2020-10-29
  • 1970-01-01
  • 2019-07-09
  • 1970-01-01
  • 2023-02-24
  • 1970-01-01
相关资源
最近更新 更多