0

I have a Product model

class Product {

    String name;
    ArrayList<ProductFeature> productFeatures;
}

I have a ProductFeature model

class ProductFeature {

    String name;
    String value;
}

Product Features name-value pairs

  1. For name "Color", value can be [black, red, yellow, etc]
  2. For name "Size", value can be [34, 38, 42, 46, 47, etc]
  3. For name "Weight", value can be [10K, 20K, 40K, 41K, etc]

For one name, there will be only one value. A Product can't have two ProductFeatures with same name.

I have many products, stored in an ArrayList of Product e.g. For Product (feature, feature, feature), I have following data :-

e.g. (color, size, weight)

#1 Product ( black,  34, 10.12 )
#2 Product ( yellow, 39, 20.00 )
#3 Product ( black,  67, 22.97 )
#4 Product ( red,    12, 48.21 )
#5 Product ( red,    52, 12.13 )
#6 Product ( blue,   85, 10.00 )*
#7 Product ( blue,   10, 80.00 )
#8 Product ( fire,   87, 40.52 )

Back-end says that a product with these features is selected

[color=blue, size=85, weight=10.00]

I store these features in a HashMap<String, String>

[
  (color,  blue),
  (size,   85),
  (weight, 10.00)
]

I have to find this selected product with these features from my list of products

for (Product product : products) {

    ArrayList<ProductFeature> productFeatures = product.getProductFeatures();

    // I am stuck here
}

How do I compare this list productFeatures with my HashMap<String, String> to find out which product from products has all the features from HashMap?

If more information is needed, please ask.

Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
rupinderjeet
  • 2,984
  • 30
  • 54
  • Couple of tips: Don't use implementation classes (ArrayList) for attributes, also you are coding in a statically typed language, take advantage of it instead of using String – DPM Sep 21 '17 at 18:00
  • @DPM can you elaborate on this please? Maybe post a link so that I can understand all of your comment. – rupinderjeet Sep 21 '17 at 18:21
  • For my first point: https://stackoverflow.com/a/383982/1045902 About the second, I mean that if you are going to pay for Java verbosity at least make meaningful classes, or enums instead of strings. But this is opinionable. – DPM Sep 21 '17 at 23:07

2 Answers2

1

I highly suggest you go for a completely different design.

class Product {
    String name;
    ProductFeature productFeatures;
}

class ProductFeature {
    String color;
    int size;
    double weight;
}

Let's say, you want to find a yellow Product with the same size and weight of 20. You can simply compare its ProductFeature to get the desired one. Of course, don't forget to override the equals() method to compare features correctly:

ProductFeature compared = new ProductFeature("Yellow", 20, 20.0);
Product returned = null;

for (Product product : products) {
    ProductFeature current = product.getProductFeature;
    if (current.equals(compared) {
        returned = product;
        break;
    }
}

// now the variable 'returned' contains the product that matches the characteristics.
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • Thanks, but `color`, `size`, `weight` are examples. There can be `ram`, `storage`, `processer`. All of them are dynamic, that's why I used name-value pairs. – rupinderjeet Sep 21 '17 at 18:07
1

You could do something like below:

private Product findMatch( List<Product> products, Map<String, String> map )
{

    for (Product product : products) 
    {

        ArrayList<ProductFeature> productFeatures = product.getProductFeatures();

        boolean found = true;
        for ( ProductFeature feature : productFeatures )
        { 
           if ( map.containsKey( feature.name ) && map.get( feature.name ).equals( feature.value ) )
           {
              continue;
           }
           found = false;
           break;
        }

        if ( found ) 
        {
           return product;
        }
    }

    return null;

}

But I strongly believe you could improve your design better for better searches.

SomeDude
  • 13,876
  • 5
  • 21
  • 44
  • This is the approach I needed. Thanks. Keeping in mind that `color`, `size`, `weight` are completely random(there can be any names and any number of names), how can I improve design on my side? I, only, converted received data from Backend into a HashMap. – rupinderjeet Sep 21 '17 at 18:11