结合列表子集,Java生成列表 [英] Generate List with Combination of Subset of List, Java

查看:97
本文介绍了结合列表子集,Java生成列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题将用Java实现.

This question is to be implemented in Java.

我有一个名为竞争者"的类,具有类型",名称"和权限".

I have a class named Competitor, with Type, Name and Power.

public class Competitor {
  private final int type;
  private final String name;
  private final int power;

  public Competitor(int type, String name, int power) {
    this.type = type;
    this.name = name;
    this.power = power;
  }

  public int getType() {
    return type;
  }

  public String getName() {
    return name;
  }

  public int getPower() {
    return power;
  }

  @Override
  public String toString() {
    return "Competitor{" + "type=" + type + ", name=" + name + ", power=" + power + '}';
  }

}

现在,我想做一个游戏,type有一个竞争对手,类型的数量可以是60(3D arrays或嵌套的for对我来说不是解决方案).

Now, I want to do a game, with ONE competitor by type, the numbers of type can be 60 (3D arrays or nested for is not a solution for me).

我想生成此列表的子集(按类型分类)的所有可能组合.

I want to generate all posible combination of sub Set (classified by type) of this List.

public class Game {
  public static void main(String... args) {
    List<Competitor> listCompetitors = new ArrayList<>();
    listCompetitors.add(new Competitor(1, "Cat 00", 93));
    listCompetitors.add(new Competitor(1, "Cat 10", 11));
    listCompetitors.add(new Competitor(1, "Cat 23", 20));

    listCompetitors.add(new Competitor(2, "Dog 61", 54));
    listCompetitors.add(new Competitor(2, "Dog 18", 40));
    listCompetitors.add(new Competitor(2, "Dog 45", 71));
    listCompetitors.add(new Competitor(2, "Dog 30", 68));

    listCompetitors.add(new Competitor(3, "Pig 90", 90));
    listCompetitors.add(new Competitor(3, "Pig 78", 32));

    listCompetitors.add(new Competitor(4, "Cow 99", 90));

    // The type is NOT fixed number (is variable from 1 to 60)
  }
}

如何生成类似...的组合

How is possible generate the combination like...

new Competitor(1, "Cat 00", 93)
new Competitor(2, "Dog 61", 54)
new Competitor(3, "Pig 90", 90)
new Competitor(4, "Cow 99", 90)

另一种组合

new Competitor(1, "Cat 00", 93)
new Competitor(2, "Dog 61", 54)
new Competitor(3, "Pig 78", 32)
new Competitor(4, "Cow 99", 90)

...

最后一个组合

new Competitor(1, "Cat 23", 20)
new Competitor(2, "Dog 30", 68)
new Competitor(3, "Pig 78", 32)
new Competitor(4, "Cow 99", 90)

如何像以前建议的那样生成子列表?

How generate sublist like proposed before?

我也下注.

考虑功率参数. List<Competitor>性能(最低功率总和)和最佳(最大参数总和)是什么?

Taking in account the power parameter. What is are the List<Competitor> the worse(minimum sum of power) and best (maximum sum of parameter) performance?

推荐答案

首先,按类型对所有元素进行分组,以获取要组合的列表.

First, group all elements by type, to get the lists to combine.

Map<Integer, List<Competitor>> map
    = listCompetitors.stream().collect(Collectors.groupingBy(Competitor::getType));

然后,要构建笛卡尔乘积,我们需要一个辅助方法来从现有的List和其他元素中创建一个新的List.不幸的是,没有内置的方法(但是您可能会在第三方库中找到此类操作)

Then, to build the Cartesian Product, we need a helper method to create a new List out of an existing List and an additional element. Unfortunately, there’s no built-in method for that (but you might find such operations in 3rd party libraries though)

static <T> List<T> listWith(List<T> list, T t) {
    List<T> result = new ArrayList<>(list.size() + 1);
    result.addAll(list);
    result.add(t);
    return result;
}

这样,我们可以构造一个Stream并将其收集到结果List中:

With that, we can construct a Stream and collect it into a result List:

Stream<List<Competitor>> stream = Stream.of(Collections.emptyList());
for(List<Competitor> next: map.values())
    stream = stream.flatMap(list -> next.stream().map(c -> listWith(list, c)));

List<List<Competitor>> listOfListCompetitor = stream.collect(Collectors.toList());

每个flatMap步骤都会将流与另一个维度合并.

Each flatMap step will combine the stream with another dimension.

listWith的收集操作也可以通过其他流操作完成,例如

The collection operation of listWith could also be done with another stream operation, e.g.

Stream<List<Competitor>> stream = Stream.of(Collections.emptyList());
for(List<Competitor> next: map.values())
    stream = stream.flatMap(list -> next.stream()
        .map(c -> Stream.concat(list.stream(), Stream.of(c)).collect(Collectors.toList())));

List<List<Competitor>> listOfListCompetitor = stream.collect(Collectors.toList());

但这不是那么直观,恕我直言.

but that’s not as intuitive, imho.

这篇关于结合列表子集,Java生成列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆