迭代hashmap并创建独特的对象 - 试图防止重复 [英] Iterating through hashmap and creating unique objects - trying to prevent duplicates

查看:102
本文介绍了迭代hashmap并创建独特的对象 - 试图防止重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public int addPatron(String name )抛出PatronException {
int i = 0;
// 1。 (Map.Entry< Integer,Patron>条目:patrons.entrySet()){$())中的hashmap
中不存在新名称, b $ b赞助人nameTest = entry.getValue();
// 2。如果我想添加的名称已经存在,我们希望抛出一个异常。
if(nameTest.getName()== name){
throw new PatronException(This patron already exists);
// 3。如果该名称是唯一的,我们希望获得散列中已经存在的最大关键值(客户编号),并将其加1。
} else if(nameTest.getName()!= name){
Map.Entry< Integer,Patron> maxEntry = null; (Map.Entry< Integer,Patron> entryCheck:patrons.entrySet()){
if(maxEntry == null || entryCheck.getKey()> maxEntry.getKey()){
maxEntry = entryCheck;
i = maxEntry.getKey();
i ++;
}
}

}其他{
抛出新的PatronException(某事不行!);
}
// 4。如果在此之前一切正常,我们希望给我们提供名称和新的客户ID号码,然后使用它们创建一个新的Patron对象,然后将其添加到包含所有用户的此类的hashmap中。
赞助人newPatron =新赞助人(姓名,我);
patrons.put(i,newPatron);
}
返回i;
}

当我尝试运行一个简单的单元测试时,如果我成功添加

  try {
testLibrary.addPatron(Dude );
testLibrary.addPatron(Dude);
失败(这不应该起作用);

测试失败,告诉我addPatron方法能够使用同一个名字两次。

@Jon Skeet:



我的Patron类看起来像这样:

  public class Patron {

// attributes
private String name = null;
private int cardNumber = 0;

//操作
public Patron(String name,int cardNumber){
this.name = name;
this.cardNumber = cardNumber;
}

public String getName(){
return name;

}

public int getCardNumber(){
return cardNumber;
}

}

正如其他人所说,使用 == 来比较字符串几乎肯定是不合适的。但是,它不应该在你的测试用例中引起问题,因为你使用了相同的常量字符串两次,所以 == 应该可以工作。当然,你仍然应该修改代码来使用 equals



目前还不清楚 Patron 构造函数或 getName 方法做 - 这些都可能导致问题(例如,如果他们创建了 new 字符串的副本 - 这会导致你的测试失败,但通常也是不必要的)。



更令人担心的是这个评论:

  // 3.如果名称是唯一的,我们希望获得最大的键值(客户编号)
//已经在散列中,增加一个。

这个注释在主循环中是。所以到那个时候,我们不知道这个名字是独一无二的 - 我们只知道它在这次迭代中与赞助人的名字不匹配。



更令人担忧的是 - 我只是注意到了这一点 - 您也在迭代块内执行add 。在我看来,你应该有更多这样的东西:

  public int addPatron(String name)throws PatronException {
int maxKey = -1; (Map.Entry< Integer,Patron> entry:patrons.entrySet()){
if(entry.getValue()。getName()。equals(name)){

b $ b // TODO:考虑使用IllegalArgumentException
抛出新的PatronException(这个顾客已经存在);
}
maxKey = Math.max(maxKey,entry.getKey());
}
int newKey = maxKey + 1;
赞助人newPatron =新赞助人(姓名,newKey);
patrons.put(newKey,newPatron);
返回newKey;
}

另外,它听起来像真的从名字到赞助人的地图,可能还有ID到赞助人地图。


I explain what I am trying to do in comments above the parts in the method:

public int addPatron(String name) throws PatronException {
    int i = 0;
    //1. Iterate through a hashmap, and confirm the new name I am trying to add to the     record doesn't already exist in the hashmap
    for (Map.Entry<Integer, Patron> entry : patrons.entrySet()) {
        Patron nameTest = entry.getValue();
        //2. If the name I am trying to add already exists, we want to throw an exception saying as much.
        if (nameTest.getName() == name) {
            throw new PatronException ("This patron already exists");
            //3. If the name is unique, we want to get the largest key value (customer number) already in the hash, an increment by one.
        } else if (nameTest.getName() != name) {
            Map.Entry<Integer,Patron> maxEntry = null;
            for(Map.Entry<Integer, Patron> entryCheck : patrons.entrySet()) {
                if (maxEntry == null || entryCheck.getKey() > maxEntry.getKey()) {
                    maxEntry = entryCheck;
                    i = maxEntry.getKey();
                    i++;
                }
            }

        } else {
            throw new PatronException("Something's not working!");
        }
        //4. If everything is ok up to this point, we want to us the name and the new customer id number, and use those to create a new Patron object, which then gets added to a hashmap for this class which contains all the patrons.
        Patron newPatron = new Patron(name, i);
        patrons.put(i, newPatron);
    }
    return i;
}

When I try and run a simple unit test that will fail if I successfully add the same name for addPatron twice in a row, the test fails.

try {
    testLibrary.addPatron("Dude");
    testLibrary.addPatron("Dude");
    fail("This shouldn't have worked");

The test fails, telling me the addPatron method is able to use the same name twice.

@Jon Skeet:

My Patron class looks like this:

public class Patron {

//attributes
private String name = null;
private int cardNumber = 0;

//operations
public Patron (String name, int cardNumber){
    this.name = name;
    this.cardNumber = cardNumber;
}

public String getName(){
    return name;

}

public int getCardNumber(){
    return cardNumber;
}

}

解决方案

As others have said, the use of == for comparing strings is almost certainly inappropriate. However, it shouldn't actually have caused a problem in your test case, as you're using the same constant string twice, so == should have worked. Of course, you should still fix the code to use equals.

It's also not clear what the Patron constructor or getName methods do - either of those could cause a problem (e.g. if they create a new copy of the string - that would cause your test to fail, but would also be unnecessary usually).

What's slightly more worrying to me is this comment:

// 3. If the name is unique, we want to get the largest key value (customer number) 
// already in the hash, an increment by one.

This comment is within the main loop. So by that point we don't know that the name is unique - we only know that it doesn't match the name of the patron in this iteration.

Even more worrying - and I've only just noticed this - you perform the add within the iteration block too. It seems to me that you should have something more like this:

public int addPatron(String name) throws PatronException {
    int maxKey = -1;

    for (Map.Entry<Integer, Patron> entry : patrons.entrySet()) {
        if (entry.getValue().getName().equals(name)) {
            // TODO: Consider using IllegalArgumentException
            throw new PatronException("This patron already exists");
        }
        maxKey = Math.max(maxKey, entry.getKey());
    }
    int newKey = maxKey + 1;
    Patron newPatron = new Patron(name, newKey);
    patrons.put(newKey, newPatron);
    return newKey;
}

Additionally, it sounds like really you want a map from name to patron, possibly as well as the id to patron map.

这篇关于迭代hashmap并创建独特的对象 - 试图防止重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆