我对Java 8还是很陌生,想重写一些代码。

任何想法如何写这个漂亮?

这个想法是,一个人有许多单位。一个单元有许多要求。我们要收集每个单元的所有要求,并将其乘以人员的数量。最后,我们要为每个不同的单位输出名称和金额。

数据示例:
人“ a”
-拥有“ u1”单元10次
-拥有“ u2”单元15次

u1单元
-需要单位“ u2” 3次
-需要单位“ u3” 1次

u2单元
-需要单位“ u3” 3次

结果应为:
Your reserved Units:\#\# 30x u2\#\# 55x u3

Java 7中的代码如下所示:

    System.out.println("Your reserved Units: ");
    final Map<Unit, Integer> allRequirements = new HashMap<Unit, Integer>();
    // for each unit that is assigned to the person
    for (UnitAmountPerson unitAmountPerson : person.getUnitAmounts()) {

        // go through each unit that is a requirement for this unit
        for (UnitAmountRequirements requirements : unitAmountPerson.getUnit().getRequirements()) {

            // calculate the amount of requirements
            final Unit requiredUnit = requirements.getUnit();
            final int requiredAmount = unitAmountPerson.getAmount() * requirements.getAmount();

            if (!allRequirements.containsKey(requiredUnit)) {
                allRequirements.put(requiredUnit, 0);
            }

            allRequirements.put(requiredUnit, allRequirements.get(requiredUnit) + requiredAmount);
        }
    }

    for (Entry<Unit, Integer> entry : allRequirements.entrySet()) {
        System.out.println("## " + entry.getValue() + "x " + entry.getKey());
    }`


实体看起来像这样:
人.java

public class Person{)
    private Set<UnitAmountPerson> unitAmounts = new HashSet<UnitAmountPerson>();

    public Set<UnitAmountPerson> getUnitAmounts() {
        return unitAmounts;
    }
}


单元库

public class Unit {
    private String name;

    private Set<UnitAmount> unitAmounts = new HashSet<UnitAmount>();

    private Set<UnitAmountRequirements> requirements = new HashSet<UnitAmountRequirements>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<UnitAmountRequirements> getRequirements() {
        return requirements;
    }

    public Set<UnitAmount> getUnitAmounts() {
        return unitAmounts;
    }
}


UnitAmount.java

public class UnitAmount {
    private Unit unit;
    private int amount;

    public Unit getUnit() {
        return unit;
    }

    public void setUnit(Unit unit) {
        this.unit = unit;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }
}


UnitAmountPerson.java

public class UnitAmountPerson extends UnitAmount {
    private Person owner;

    public Person getOwner() {
        return owner;
    }

    public void setOwner(Person owner) {
        this.owner = owner;
    }
}


UnitAmountRequirement.java

public class UnitAmountRequirements extends UnitAmount {
    private Unit owner;

    public Unit getOwner() {
        return owner;
    }

    public void setOwner(Unit owner) {
        this.owner = owner;
    }
}

最佳答案

您可以具有以下内容:

Map<Unit, Integer> allRequirements =
    person.getUnitAmounts()
          .stream()
          .flatMap(unitAmountPerson ->
             unitAmountPerson.getUnit()
                             .getRequirements()
                             .stream()
                             .map(r -> new AbstractMap.SimpleEntry<>(unitAmountPerson.getAmount(), r))
          )
          .collect(Collectors.toMap(
             e -> e.getValue().getUnit(),
             e -> e.getKey() * e.getValue().getAmount(),
             Integer::sum
          ));


此代码在单位数量上创建一个Stream。对于其中每一个,我们需要存储其数量和要求列表;为此,我们将流平面映射到Stream<Map.Entry>,其中键是该单位数量的金额,而值是平面映射的要求。由于API中没有内置的元组,因此我们不得不使用AbstractMap.SimpleEntry这样的临时数据保存器来保存这两个值。

最后,将此流收集到Map,其中键是需求的单位,而值是单位数量和需求数量的乘积。如果值重复,则将这些值相加。

10-06 14:39