简体   繁体   English

在哈希图中搜索对象内的标签

[英]Searching for tags within an object in a hashmap

I am trying to set up a search function where the user can search for a food item based on user input. 我正在尝试建立一个搜索功能,用户可以根据用户输入来搜索食物。 The items in the HashMap are set up to have the UUID of a Food class object and the object itself. HashMap中的项目设置为具有Food类对象和对象本身的UUID。

This is the repository for the food items 这是食品的仓库

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class FoodRepository {

    // Create a hash map
    private HashMap foods = new HashMap();

    // Constructor
    public FoodRepository () {

        //Food Objects
        NutritionFacts cokeNutritionFacts = new NutritionFacts(190, 0, 60, 54, 54, 0);
        String[] cokeTags = {"Drink", "Cola", "Coca-Cola"};
        Food coke = new Food("Coca-Cola", cokeNutritionFacts, cokeTags);
        foods.put(coke.getUUID(), coke);

        NutritionFacts drpepperNutritionFacts = new NutritionFacts(180, 0, 75, 48, 47, 0);
        String[] drpepperTags = {"Drink", "Cola", "Dr Pepper"};
        Food drpepper = new Food( "Dr Pepper", drpepperNutritionFacts, drpepperTags);
        foods.put(drpepper.getUUID(), drpepper);

        NutritionFacts cfaSandwichNutritionFacts = new NutritionFacts(440, 19, 1350, 40, 5, 28);
        String[] cfaSandwichTags = {"Entree", "Sandwich", "Dinner", "Lunch", "Chick Fil A"};
        Food cfaSandwich = new Food( "Chick Fil A Chicken Sandwich", cfaSandwichNutritionFacts, cfaSandwichTags);
        foods.put(cfaSandwich.getUUID(), cfaSandwich);

        NutritionFacts bigMacNutritionFacts = new NutritionFacts(540, 28, 940, 42, 9, 25);
        String[] bigMacTags = {"Entree", "Burger", "Dinner", "Lunch", "McDonalds"};
        Food bigMac = new Food( "McDonalds Big Mac", bigMacNutritionFacts, bigMacTags);
        foods.put(bigMac.getUUID(), cfaSandwich);

        // Get a set of the entries
        Set foodSet = foods.entrySet();
    }

    // Getter methods
    public HashMap getFoods() {
        return foods;
    }

    // Setter methods
    public void setFoods(HashMap foods) {
        this.foods = foods;
    }
}

This is the Food class which defines the objects going into the HashMap (getters and setters omitted) 这是Food类,它定义进入HashMap的对象(省略了getters和setters)

public class Food {
    // Class variables
    private String uuid;
    private String name;
    private NutritionFacts nutritionFacts;
    private String[] tags;

    // Constructor
    public Food(String name, NutritionFacts nutritionFacts, String[] tags) {
        this.uuid = UUID.randomUUID().toString();
        this.name = name;
        this.nutritionFacts = nutritionFacts;
        this.tags = tags;
    }
}

And finally, this is the nutrition facts class 最后,这是营养事实课

public class NutritionFacts {
    // Class Variables
    private int calories;
    private int fat;
    private int sodium;
    private int carbs;
    private int sugar;
    private int protein;

    //private int iron;
    //private int calcium;
    //private int vitaminA;
    //private int VitaminC;

    //Constructor
    public NutritionFacts(int calories, int fat, int sodium, int carbs, int sugar, int protein){
        this.calories = calories;
        this.fat = fat;
        this.sodium = sodium;
        this.carbs = carbs;
        this.sugar = sugar;
        this.protein = protein;
    }
}

A note, I'm sorry if this is too much; 注意,如果太多,我很抱歉; this is my partner and I's first time using android studio and we are both rather inexperienced with java. 这是我的搭档,也是我第一次使用android studio,我们对Java都缺乏经验。

We had been thinking something along these lines could work: 我们一直在考虑以下方面的工作可能会起作用:

int caloriesConsumed = 0;
String searchValue = scan.nextString();
boolean flag = Arrays.asList(foods.get(key).tags).contains(searchValue);   if(flag == true) {
     caloriesConsumed = (caloriesConsumed + xxx;}

But the problem is that if the user is searching for the food using a tag like "burger" hoping for a big mac to show, that method requires the key to be known and in the code; 但是问题是,如果用户正在使用“汉堡”之类的标签搜索食品,希望显示一个大型Mac,则该方法需要知道密钥并在代码中; thus, defeating the purpose of searching along the value. 因此,破坏了追求价值的目的。

Alternatively we have seen some people use methods like this: 另外,我们已经看到有些人使用这样的方法:

String needle = "burger"
for(Map.Entry<String, Food> entry : foods.entrySet()) {
     Food v = entry.getValue();
     if(v.contains(needle))
          caloriesConsumed = (caloriesConsumed + xxx);
     }

but the .contains() method doesn't work for strings / isn't compatible since the HashMap's value is a special object and not a regular data type. 但是.contains()方法不适用于字符串/不兼容,因为HashMap的值是一个特殊的对象,而不是常规的数据类型。

Thanks for any and all help, it is much appreciated! 感谢您提供的所有帮助,非常感谢!

The last snippet could be a working solution. 最后一个片段可能是一个可行的解决方案。

if(v.contains(needle)){
    caloriesConsumed = (caloriesConsumed + xxx);
}

Here, v is a type of Food, so obviously it doesn't have a contains method as you not implemented it. 在这里,v是食物的一种,因此很明显它没有包含方法,因为您没有实现它。 As i see you will need to search in the v.tags field, but it is an array of Strings, which doesn't have contains method. 如我所见,您将需要在v.tags字段中进行搜索,但这是一个字符串数组,其中没有contains方法。 I would suggest to change the tags field's type from String[] to List< String >, and then you can use tags.contains(needle) to look for the specified search item in tags. 我建议将标签字段的类型从String []更改为List <String>,然后可以使用tags.contains(needle)在标签中查找指定的搜索项。

Edit: For the Map< String,Food> issue 编辑:对于Map <String,Food>问题

In your code I see you use raw HashMap type 在您的代码中,我看到您使用原始的HashMap类型

// Create a hash map
private HashMap foods = new HashMap();

The problem is, that in that way, noone knows that this is a String,Food hashmap, so obviously you will get error if you want to assign it to a String,Food entry. 问题是,以这种方式,没有人知道这是一个String,Food哈希图,因此,如果您想将其分配给String,Food条目,显然会得到错误。

I suggest using it like that: private Map< String, Food > foods = new HashMap<>(); 我建议这样使用它:private Map <String,Food> foods = new HashMap <>();

Also change the getter setter to return/accept Map< String, Food> 还要将getter setter更改为return / accept Map <String,Food>

Note: Using Interfaces instead of concrete types is a better approach in programming, but if you still want to specify that this is a HashMap (which i can't see why you would, but lets assume) then declare your variable as HashMap< String,Food> foods 注意:在编程中,使用接口而不是具体类型是一种更好的方法,但是如果您仍然想指定这是一个HashMap(我看不到为什么,但是假设),则将变量声明为HashMap <String ,食品>食品

That should do the job :) 那应该做的工作:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM