简体   繁体   English

使用地图界面在类的实现的“结构”中查找值

[英]Using map interface to look for a value in a 'struct' like implementation of class

Im a beginner in Java, I am trying to implement a struct like data structure in Java using classes and I want to look for a match in that...This question might have been asked before, but Im not able to find it. 我是Java的初学者,我正在尝试使用类在Java中实现类似于数据结构的结构,并且我想在其中寻找匹配项……这个问题可能之前曾有人提出过,但我找不到它。 Please help. 请帮忙。 The code is as follows: 代码如下:

public class operations extends DefFunctionHandler {  

public Integer stream;  
public Integer funct;  
public String name;  
public Integer funcgroup;  
public Integer source;  
}  
 //in another class
 public void execute(String x) {  

 List<operations> oplist = new ArrayList<operations>();  
 operations op = new operations();  

 for(int i=0; i< functi.size();i++){  
     op.stream = str.get(i);  
     op.funct = functi.get(i);  
     op.funcgroup = functigroup.get(i);  
     op.name = nme.get(i);  
     op.source = src.get(i);  

}  

 oplist.add(op);
 Map<String, List<operations>> map = new HashMap<String, List<operations>>();

 map.put(x, oplist);
 List<operations> ope = map.get(x);
 for (Map.Entry<String, List<operations>> entry : map.entrySet()) {
      String key = entry.getKey();
      List<operations> value = entry.getValue();
      System.out.println(value);
    } 

} 

As seen, I have a class operations , in which I have various fields. 可以看到,我有一个类operations ,其中有多个领域。 In another method called execute , I add values into those fields in the form of array. 在另一种称为execute方法中,我将值以数组的形式添加到这些字段中。 Now I get an input from the user for name , I want to search for it in the class/struct implementation and return the corresponding value for stream to the user. 现在,我从用户那里获得了name的输入,我想在class / struct实现中搜索它,并将流的相应值返回给用户。 I understand that I have to implement a Map interface, but how do I do it? 我了解必须实现Map接口,但是我该怎么做呢? When I try to print value , I get otf.operations@3934f69a Is my implementation of Map Interface and get method correct? 当我尝试打印value ,我得到otf.operations@3934f69a我的Map Interface实现和get方法正确吗? Im confused. 我糊涂了。 Please help. 请帮忙。

EDIT The code for the execute method now looks like this 编辑 execute方法的代码现在看起来像这样

 public void execute(String x) {

    Map<String,Operations> obs = new HashMap<String,Operations>();  

    for(int i=0; i< functi.size();i++){
        Operations op = new Operations();
        op.stream = str.get(i);
        op.funct = functi.get(i);
        op.funcgroup = functigroup.get(i);
        op.name = nme.get(i);
        op.source = src.get(i);

        obs.put(op.name, op);       

}
    System.out.println(obs.get(x));

}

You are trying to print a list: 您正在尝试打印列表:

System.out.println(value)

where value is a List<operations> . 其中value是List<operations> What you would like to do is to print the values of that list. 您要做的是打印该列表的值。 Then do something like: 然后执行以下操作:

for (operations o : value) {
    System.out.println(o.stream);
    System.out.println(o.name);
}

EDIT the code you need: 编辑所需的代码:

public void execute(String x) {


      ArrayList<operations> ops= new ArrayList<operations>();
      for(int i=0; i< functi.size();i++) {
         operations op = new operations();
         op.stream = str.get(i);
         op.funct = functi.get(i);
         op.funcgroup = functigroup.get(i);
         op.name = nme.get(i);
         op.source = src.get(i);
         ops.add(op);
      }


     Map<String,ArrayList<operations>> map = new HashMap<String, ArrayList<operations>>();
     map.put(x, ops);

     for (operations operation : map.get(x)) {
         System.out.println(operation.name);
     }

}

First of all value is List<Operations> , so to iterate over each, you can do 首先, valueList<Operations> ,因此要遍历每个值,您可以

for(Operations o : value) {
   System.out.println(o);
}

If you get a chance to see the implementation of System.out.printlin(object) , it will print object.toString() 如果您有机会看到System.out.printlin(object)的实现,它将打印object.toString()

So otf.operations@3934f69a is the string returned by the method toString() which is by default inherited from java.lang.Object class (since all classes implicitly extend Object ). 所以otf.operations@3934f69a是方法toString()返回的字符串,该方法默认情况下是从java.lang.Object类继承的(因为所有类都隐式扩展Object )。 The toString() of java.lang.Object looks like this java.lang.ObjecttoString()看起来像这样

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

to change this behavior, in your Operations class, you need to override toString() method 要更改此行为,请在您的Operations类中,重写toString()方法

class Operations {

  @Overrides
  public String toString() {
     return name;
  }

}

A map can be thought of as a list with labels on each of the items, so that you can easily find an item in the list by its label. 可以将地图看作是在每个项目上都带有标签的列表,以便您可以通过列表中的标签轻松地找到一个项目。 What is the label? 标签是什么? Well, in the context of Java it is called a key, and can be many types. 好吧,在Java的上下文中,它称为密钥,可以有很多类型。 Most times it is a String, but it can also be any object which implements equals(Object obj) and hashCode() properly (which String already does). 大多数情况下,它是一个字符串,但也可以是任何可以正确实现equals(Object obj)hashCode() equals(Object obj) (String已经完成)。

Lets see how you would insert objects into a list: 让我们看看如何将对象插入列表:

List<operations> list = new ArrayList<operations>();
for(int i=0; i functi.size(); i++) {
  operations op = new operations();
  op.stream = str.get(i);  
  op.funct = functi.get(i);  
  op.funcgroup = functigroup.get(i);  
  op.name = nme.get(i);  
  op.source = src.get(i);

  list.add(op);   
}

Notice here that inside the loop , I am calling new operations and then I am adding it to the list. 请注意, 在循环内部 ,我正在调用新operations ,然后将其添加到列表中。 This is because I want to create a new instance of operations and add it to the list for each potential operation I can create. 这是因为我要创建一个新的operations实例,并将其添加到我可以创建的每个潜在操作的列表

What would happen if I used the same instance? 如果我使用相同的实例会怎样? I would set its members again and again with different values, and insert that same instance into the list (yes, a list can contain the same instance many times over). 我会用不同的值一次又一次地设置其成员,然后将相同的实例插入列表(是的,列表可以多次包含相同的实例)。 What it would seem like is that you inserted a list containing operations all with the same value (which happen to coincide with the last operation). 会是什么看起来是你插入包含列表operations具有相同值的所有(这正好与上次操作一致)。 This is because when you set the property of an instance, all references to the same instance get changed as well (think pointers). 这是因为当您设置实例的属性时,对同一实例的所有引用也会更改(请考虑指针)。 So, in other words, be sure to create a new instance each time (You don't have to worry about deleting it later. That gets done automatically). 因此,换句话说,请确保每次都创建一个新实例(您不必担心以后再删除它。它会自动完成)。

In order to use a map, you only have to change the logic ever so slightly. 为了使用地图,您只需要稍微改变一下逻辑即可。 Rather than call add, you use put, and you must provide its key. 除了使用add之外,还没有调用add,而是必须提供其密钥。 When you need it later, you must provide its key rather than its number. 以后需要时,必须提供其密钥而不是其编号。 Here is how you would add it to a map: 将其添加到地图的方法如下:

Map<String, operations> map = new HashMap<String, operations>();
for(int i=0; i functi.size(); i++) {
  operations op = new operations();
  op.stream = str.get(i);  
  op.funct = functi.get(i);  
  op.funcgroup = functigroup.get(i);  
  op.name = nme.get(i);  
  op.source = src.get(i);

  map.put(op.name, op);   
}

Later, to retrieve a value, I only have to do map.get("juggling") , and if it exists in the map, it will give me that particular instance of operations , otherwise it will give me null . 稍后,要检索一个值,我只需要执行map.get("juggling") ,如果它存在于地图中,它将为我提供特定的operations实例,否则将为我提供null

You should note several things here: 您应该在这里注意几件事:

  • In this way, operations with duplicate names are overridden . 这样,具有重复名称的操作将被覆盖 If you have no duplicates, there is no problem. 如果没有重复项,那就没有问题。 Otherwise, you may consider making your key more specific or making your map hold a List of operations instances (on first put for that key, you must create the list instance and add it to the map). 否则,您可以考虑使键更具体,或者使地图包含operations实例List (首先放置该键时,必须创建列表实例并将其添加到地图中)。
  • This approach is ideal if you access only with its key. 如果仅使用其密钥进行访问,则此方法非常理想。 If you want to also access it as a list, you should prefer LinkedHashMap instead of HashMap (don't use unless you think you will require both, as it is slightly more expensive, but it maintains insertion order). 如果您还希望以列表形式访问它,则应首选LinkedHashMap而不是HashMap (除非您认为两者都需要,否则不要使用,因为它稍贵一些,但它会保持插入顺序)。

Also, a couple best practice notes: 另外,一些最佳实践说明:

  • Consider adding setters and getters to operations . 考虑在operations添加setter和getter。 It may not help you in this particular program, but it is best practice and will help you in other programs without a doubt. 它可能无法在此特定程序中为您提供帮助,但这是最佳实践,并且无疑会在其他程序中为您提供帮助。
  • Java class names start with a capital letter normally. Java类名通常以大写字母开头。 Method names and member names are camelCase. 方法名称和成员名称是camelCase。
  • You usually do not make Java class names "plural" unless it is a container of some sort. 除非它是某种容器,否则通常不要将Java类名设置为“复数”。 In other words, I would expect a single operation to be called Operation , and a list of Operation instances to be called Operations . 换句话说,我希望将单个操作称为Operation ,并将一个Operation实例列表称为Operations

Hope that helps! 希望有帮助!

Some advice: 一些忠告:

As you named it "struct" I guess you come from C. In Java you just have to create a "bean" which is an object which only has getters and setters (the attributes are usually declared as private so you'll need a getX() and setX(value) methods to access and modify them). 正如您将其命名为“ struct”一样,我猜您来自C。在Java中,您只需要创建一个“ bean”,该对象仅包含getter和setter(属性通常声明为private,因此您需要一个getX ()和setX(value)方法来访问和修改它们)。 That's your "operations" class, more or less. 这或多或少是您的“操作”课。

Class names always start with capital letters (Java convention). 类名始终以大写字母开头(Java约定)。

if you need to find quickly a bean/struct by a value, then store it in a Map: 如果您需要通过值快速查找bean /结构,则将其存储在Map中:

Map<String, operations> map = new HashMap<String, operations>();
map.put(myOperation.getName(),myOperation);

Then, you can obtain that bean just writing map.get(name). 然后,只需编写map.get(name).就可以获取该bean map.get(name).

Last thing, you have to implement the method toString() in any object you want write easily 最后,您必须在要轻松编写的任何对象中实现toString()方法

EDIT: I think you don't need a list, just put directly each element in a map and remove the list, something like: 编辑:我认为您不需要列表,只需将每个元素直接放在地图上并删除列表,类似:

Map<String,operations> oplist = new HashMap<String,Operations>();  
 operations op = new operations();  

 for(int i=0; i< functi.size();i++){  
     op.stream = str.get(i);  
     op.funct = functi.get(i);  
     op.funcgroup = functigroup.get(i);  
     op.name = nme.get(i);  
     op.source = src.get(i);
     oplist.put(op.name,op);  //You forgot this! it must be in the loop

}  

Then you can find any operation by name (I'm supposing name is unique) 然后,您可以按名称查找任何操作(我想名称是唯一的)

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

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