マップキーが対象であるJavaの8ソートのHashMap <文字列、整数>

vscoder:

私はそうのような単純なCustomerクラスを持っています

public class Customer {
    public int age;
    public int discount;
    public String name;

    public Customer(String name) {
        this.name = name;
    }
    public Customer(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Customer(String name, int age, int discount) {
        this.name = name;
        this.age = age;
        this.discount = discount;
    }

    @Override
    public String toString() {
        return "Customer [age=" + age + ", discount=" + discount + ", name=" + name + "]";
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Integer getDiscount() {
        return discount;
    }
    public void setDiscount(int discount) {
        this.discount = discount;
    }
}

私はこれを使用して、これらのオブジェクトのリストを作成します

List<Customer> customerList = new ArrayList<>(Arrays.asList(
        new Customer("John",   2, 15),
        new Customer("John",   4, 15),
        new Customer("John",   6, 25),
        new Customer("Joe",    3, 15),
        new Customer("Joe",    3, 15),
        new Customer("Joe",    3, 15),
        new Customer("Goerge", 6, 25),
        new Customer("Goerge", 6, 25),
        new Customer("Mary",   7, 25),
        new Customer("Jane",   1, 15),
        new Customer("Jane",   2, 15),
        new Customer("Jane",   8, 25),
        new Customer("Jane",   8, 25)
        ));

今、私はグループにしたいと、このようなコレクタを使用して、名前と割引を数えます

Map<Object, Long> collected = customerList
    .stream()
    .collect(Collectors.groupingBy(x -> Arrays.asList(x.name, x.discount), Collectors.counting()));

私はこれを使用して、私の出力を確認することができます

collected.entrySet().forEach(c -> {
    System.out.println(c);
});

これは次のように出力

[Jane, 15]=2
[Joe, 15]=3
[John, 15]=2
[Mary, 25]=1
[John, 25]=1
[Jane, 25]=2
[Goerge, 25]=2

質問は、私はどうすればよいです並べ替え、それは次のようになりますので、名前と割引で地図を

[Goerge, 25]=2
[Jane, 15]=2
[Jane, 25]=2
[Joe, 15]=3
[John, 15]=2
[John, 25]=1
[Mary, 25]=1

私は、コレクタによって返されるオブジェクトタイプに対してアップぶつけ続けますか?

それはのようなものかもしれない、クラスを返すようにすることができます私は、コレクタをキャスト

private class DiscountCounts
{
    public String name;
    public Integer discount;
}

変換することが可能であるMap<**Object**, Long>()ようなものにMap<DiscountCounts, Long>()、これはラムダまたはコンパレータの構築物を用いてマップキーのフィールドへのアクセスを許可しますか?

私はマップ上で、反復をこのような何かを試してみましたが、欲しい手動地図Iに変換するが、私は元のコレクションのキーに取得することはできませんか?

    Map<DiscountCounts, Long> collected2 = new HashMap<>();
    collected.entrySet().forEach(o -> {
        DiscountCounts key1 = (DiscountCounts)o.getKey();  //--> Fails here
        collected2.put((DiscountCounts)o.getKey(), o.getValue());
    });
デッドプール :

あなたは使用せずにそれを行うことができます一つの方法DiscountCountsのクラスは、最初の並べ替えリストであり、その後の操作によって模索を実行し、使用がLinkedHashMapソート順序を保存します

Map<List<Object>, Long> map = customerList.stream()
                .sorted(Comparator.comparing(Customer::getName).thenComparing(Customer::getDiscount))
                .collect(Collectors.groupingBy(x -> Arrays.asList(x.name, x.discount),LinkedHashMap::new, Collectors.counting()));

使用して別の方法DiscountCountsクラスがオーバーライドにより、あるequalshashcodeDiscountCountsクラスとgroupingBy作成行うDiscountCountsすべてのためのオブジェクトCustomerでキーとしてオブジェクトをMapし、使用TreeMapしてComparator結果をソートします

Map<DiscountCounts, Long> result = customerList.stream().collect(Collectors.groupingBy(
            c -> new DiscountCounts(c.getName(), c.getDiscount()),
            () -> new TreeMap<DiscountCounts, Long>(
                    Comparator.comparing(DiscountCounts::getName).thenComparing(DiscountCounts::getDiscount)),
            Collectors.counting()));

@Andreasはコメントで示唆私にそれを行うための別の方法を啓発し、私は、これはあなたが実装できる最善のアプローチの一つであると感じComparableDiscountCountsあなたがコンパレータに提供する必要がないように並べ替えロジックを提供し、TreeMap

@Override
public int compareTo(DiscountCounts cust) {

      int last = this.getName().compareTo(cust.getName());

     return last == 0 ? this.getDiscount().compareTo(cust.getDiscount()) : last;
}

Map<DiscountCounts, Long> result1 = customerList.stream().collect(Collectors.groupingBy(
            c -> new DiscountCounts(c.getName(), c.getDiscount()), TreeMap::new, Collectors.counting()));

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=300708&siteId=1