随意地将人们分成小组

问题描述 投票:0回答:2

我正在使用组生成器,并使用此方法对人员进行分组

public String nMix(String file, int numOfGroups) {
   ReadFile info = new ReadFile();
   ArrayList<String> studentInfo = info.readEachWord(file);

   List<PeopleClass> people = new ArrayList<PeopleClass>();
   for (int i = 0; i < studentInfo.size(); i += 4) {
      people.add(new PeopleClass(studentInfo.get(i))); //name
   }

   Collections.shuffle(people);
// System.out.println(people.get(0).getName());

   Function<PeopleClass, String> discriminator = PeopleClass::getName;
   AtomicInteger index = new AtomicInteger();
   List<List<PeopleClass>> groups = new ArrayList<>(people.stream()
      .sorted(Comparator.comparing(discriminator))
      .collect(Collectors.groupingBy(e -> index.getAndIncrement() % numOfGroups))
      .values());

   //groups.forEach(System.out::println);
   groups.forEach(System.out::println);
   String txt = "";

   for(int j = 0; j < groups.size(); j ++) {
      txt += "Group" + (j + 1);
      txt += "\r\n";
      txt += groups.get(j);
      txt += "\r\n";
      txt += "\r\n";
   }

   return txt;
}

我的班级

public PeopleClass(String name){
   this.name = name;
}

但是每次我使用它时,组似乎不是随机的,而是按照名称原始ArrayList的顺序进行分组。我应该如何解决这个问题并使其随机化。

java arraylist random shuffle
2个回答
0
投票

我能够复制并运行您的代码并获得预期的结果。我只需要进行一些更改:

1)在您的初始for循环中,您将i递增4:
for (int i = 0; i < studentInfo.size(); i += 4) {

我不知道您为什么要这样做,导致您跳过将学生从文件添加到列表的过程,所以我将其更改为以1递增i。

for (int i = 0; i < studentInfo.size(); i++) {

2)Collections.shuffle()调用按预期工作,并且如果在调用后直接打印混洗的列表,并且得到类似的结果并打印该列表,则可以看到它们已被正确混洗。

最后,您不应该在Lamda中调用.sorted(),它会再次对列表进行排序,从而破坏了Collections.shuffle()调用的目的:

    Function<PeopleClass, String> discriminator = PeopleClass::getName;
    AtomicInteger index = new AtomicInteger();
    List<List<PeopleClass>> groups = new ArrayList<>(people.stream()
          //  .sorted(Comparator.comparing(discriminator))
            .collect(Collectors.groupingBy(e -> (index.getAndIncrement() % numOfGroups)))
            .values()
    );

最后,重写toString()中的PersonClass方法也很有帮助(最好将其称为Person)。通过覆盖toString(),您可以仅返回人员的姓名,从而使整个列表的打印变得可读。

下面是您的课程的最终修改版:

public String nMix(String file, int numOfGroups) {
   ReadFile info = new ReadFile();
   ArrayList<String> studentInfo = info.readEachWord(file);

   List<PeopleClass> people = new ArrayList<PeopleClass>();
   for (int i = 0; i < studentInfo.size(); i++) {
      people.add(new PeopleClass(studentInfo.get(i))); //name
   }

   Collections.shuffle(people);
   System.out.println("Shuffled people: " + people);

   Function<PeopleClass, String> discriminator = PeopleClass::getName;
   AtomicInteger index = new AtomicInteger();
   List<List<PeopleClass>> groups = new ArrayList<>(people.stream()
      //.sorted(Comparator.comparing(discriminator))
      .collect(Collectors.groupingBy(e -> index.getAndIncrement() % numOfGroups))
      .values());

   //groups.forEach(System.out::println);
   groups.forEach(System.out::println);
   String txt = "";

   for(int j = 0; j < groups.size(); j ++) {
      txt += "Group" + (j + 1);
      txt += "\r\n";
      txt += groups.get(j);
      txt += "\r\n";
      txt += "\r\n";
   }

   return txt;
}

人员分类:

class PeopleClass {
   String name;

   public PeopleClass(String name) {
      this.name = name;
   }

   public String getName(){
      return this.name;
   }

   @Override
   public String toString() {
      return this.name;
   }
}

输入:我没有您的输入文件内容,因此使用以下示例列表:{"p1","p2","p3","p4","p5","p6","p7","p8","p9","p10"}

输出:

无序播放的人:[p8,p4,p7,p6,p9,p1,p3,p2,p5,p10]

Group1 [p8,p6,p3,p10]

Group2 [p4,p9,p2]

Group3 [p7,p1,p5]


0
投票

这里是一种方式。

© www.soinside.com 2019 - 2024. All rights reserved.