通过反射的独特产品列表?

List of unique product by reflection?

我正在寻找如何制作具有独特产品的列表(或其他东西)的解决方案。我想这样做的原因是产品的总价。每组可以包含相同的产品。

这是我的 类。

public class Product {

  public String name; // unique name
  public double price;
  public double qty;

}

&

public class Sets {
  public Product item1;
  public Product item2;
  ...
  public Product item7;
  public static listsProduct<Product> = new Arraylists<Product>();
}

我正在尝试制作列表,但我不知道如何添加独特的产品。要添加产品,我使用反射。

我的方法:

 public void getProducts() throws NoSuchMethodException, Exception {
     Sets object = this;
     Class clazz = object.getClass();
     Field[] fields = clazz.getFields();
     Method m1 = Product.class.getMethod("getname", null);
     for (Field field : fields) {
       if(field.get(object)!=null) {
         System.out.println(field.getName()+" = " + m1.invoke(field.get(object),null));
         Product e=(Product) field.get(object);
         if (listsProduct==null ) listsProduct.add((Produkt) field.get(object));
         if (!(listsProduct.contains(field.get(object)))) listsProduct.add(e);

        }
     }

它正在正确添加产品,但如何制作唯一列表?

在此先感谢您的帮助!

编辑: 那么...你想要达到什么目的?
例如

套:

1) 黄油、牛奶、花生

2) 好东西,黄油,xxx

3) 牛奶、花生、xxx

结果: 唯一产品列表

  1. 黄油

  2. 牛奶

  3. 花生

  4. xxx

  5. 好东西

如果产品存在于列表中总价

我还是不明白你为什么要使用反射,我给出下面的答案来解决你的问题 how to store unique products ?

如果您想添加独特的产品。您必须定义是什么让产品与众不同?假设产品名称将帮助您识别它们是否是 not-equal/unique.

要定义它,让我们在产品中编写 equals &hashcode 方法 class

public class Product {

  public String name; // unique name
  public double price;
  public double qty;

  public boolean equals(Object obj){
   if (obj ==null || ! obj instanceOf Prpduct) return false;
   else return ((Product) obj).name.equals(name);// also write a null check conditions for name field.
 }
 public interest hashCode(){ 
return name.hashCode();
 }

}

现在将您的数据结构从 List 更改为 Set 它将仅存储不同的 Products ,如下所示 `

public class Sets {
  public Product item1;
  public Product item2;
  ...
  public Product item7;
  public static Set<Product> productSet= new HashSet<Product>();
}

` 有了这个,只要你添加 productSet,只有唯一的会被存储。

您不需要为这样的事情使用 Reflection API

获取独特产品列表的一种方法是使用 Map::merge 并将 产品名称 作为 并且此示例中的 Product::merge 方法作为 重新映射函数 .


给定 class 产品...

public class Product {
    String name;
    double price;
    int qty;

    public Product(String name, double price, int qty) {
        this.name = name; this.price = price; this.qty = qty;
    }

    public Product merge(Product p) {
        price += p.price;
        qty += p.qty;
        return this;
    }

    @Override
    public String toString() {
        return String.format("%s x %d (%.2f)", name, qty, price);
    }
}

以及 列表 集合 产品:

List<Set<Product>> sets = asList(
    new HashSet<>(asList(new Product("cheese", 5, 1), new Product("milk", 3, 3))),
    new HashSet<>(asList(new Product("peanut", 1, 1), new Product("bread", 2, 1))),
    new HashSet<>(asList(new Product("cheese", 5, 1), new Product("peanut", 1, 1)))
);

集合 独特的产品 可以这样创建:

private static Collection<Product> listProducts(List<Set<Product>> sets) {
    Map<String, Product> uniques = new HashMap<>();
    for(Set<Product> set : sets)
        for(Product p : set)
            uniques.merge(p.name, p, (a, b) -> a.merge(b));
    return uniques.values();
}

完整的工作示例:

import static java.util.Arrays.*;
import java.util.*;

public class UniqProd {
    public static class Product {
        String name;
        double price;
        int qty;

        public Product(String name, double price, int qty) {
            this.name = name;
            this.price = price;
            this.qty = qty;
        }

        public Product merge(Product p) {
            price += p.price;
            qty += p.qty;
            return this;
        }

        @Override
        public String toString() {
            return String.format("%s x %d (%.2f)", name, qty, price);
        }
    }

    public static void main(String[] args) {
        List<Set<Product>> sets = asList(
            new HashSet<>(asList(new Product("cheese", 5, 1), new Product("milk", 3, 3))),
            new HashSet<>(asList(new Product("peanut", 1, 1), new Product("bread", 2, 1))),
            new HashSet<>(asList(new Product("cheese", 5, 1), new Product("peanut", 1, 1)))
        );

        listProducts(sets).forEach(System.out::println);
    }

    private static Collection<Product> listProducts(List<Set<Product>> sets) {
        Map<String, Product> uniques = new HashMap<>();
        for (Set<Product> set : sets)
            for (Product p : set)
                uniques.merge(p.name, p, (a, b) -> a.merge(b));
        return uniques.values();
    }
}

如果您出于某种原因must/want使用您的 Sets class 而不是 java.util.Set,请在迭代之前在您的 Sets 实例中构造一个产品列表:

private static Collection<Product> listProducts(List<Sets> sets) {
    Map<String, Product> uniques = new HashMap<>();
    for (Sets set : sets)
        for (Product p : asList(set.item1, set.item2, set.item3))
            uniques.merge(p.name, p, (a, b) -> a.merge(b));
    return uniques.values();
}