[英]Comparing Array Values and HashMap
我当时正在制作剪刀石头布的游戏,应该将用户的最后四步保存到HashMap中。 最后四次抛出将在Pattern类中。 我拥有它,以便如果该模式已经在HashMap中,则该值将增加1,表明用户已重复该模式一次。 这些模式将用于预测用户的下一步行动。 但是,当我比较两种模式时,即使HashMap中的一种和我刚刚传入的一种,即使它们不相同,它也会返回它们是相同的。 我已经尝试研究了一段时间,但是我找不到问题所在。 一些帮助将不胜感激! 错误在第二个输入处出现。 如果我输入R,它将保存在HashMap中,但是当我输入其他任何内容时,它将抛出NullPointerException,我认为是因为新模式未存储在哈希图中,但是由于程序认为,我试图获取它的值它等于HashMap内部已经存在的那个。 我认为问题出在Pattern的equals()内部,但我不确定。
import java.util.*;
public class RockPaperScisors{
public static void main(String[] args){
Scanner key = new Scanner(System.in);
Pattern pattern = new Pattern();
Pattern pattern1;
Computer comp = new Computer();
boolean stop = false;
int full=0;;
while ( !stop ){
System.out.println("Enter R P S. Enter Q to quit.");
char a = key.next().charAt(0);
if ( a == 'Q' ){
stop = true;
break;
}
pattern.newPattern(a);
char[] patt = pattern.getPattern();
for ( int i = 0; i < patt.length; i++ ){
System.out.print(patt[i] + " ");
}
pattern1 = new Pattern(patt);
comp.storePattern(pattern1);
System.out.println();
System.out.println("Patterns: " + comp.getSize());
full++;
}
}
}
import java.util.*;
public class Pattern{
private char[] pattern;
private int full = 0;
public Pattern(){
pattern = new char[4];
}
public Pattern(char[] patt){
pattern = patt;
}
public char[] getPattern(){
return pattern;
}
public void newPattern(char p){
if ( full <= 3 ){
pattern[full] = p;
full ++;
}
else{
for (int i = 0; i <= pattern.length-2; i++) {
pattern[i] = pattern[i+1];
}
pattern[pattern.length-1] = p;
}
}
public int HashCode(){
char[] a = pattern;
return a.hashCode();
}
public boolean equals( Object o ) {
if( o == this ) { return true; }
if(!(o instanceof Pattern)){ return false; }
Pattern s = (Pattern) o;
if (Arrays.equals(s.getPattern(), pattern))
System.out.println("Yes");
return Arrays.equals(s.getPattern(), pattern);
}
}
import java.util.*;
import java.util.Map.Entry;
public class Computer{
private HashMap<Pattern, Integer> map;
public Computer(){
map = new HashMap <Pattern, Integer>();
}
public void storePattern(Pattern p){
boolean contains = false;
for (Entry<Pattern, Integer> entry : map.entrySet())
{
Pattern patt = entry.getKey();
if ( p.equals(patt) ){
contains = true;
}
}
if ( contains ){
int time = map.get(p);
time++;
map.put(p, time);
}
else
map.put(p, 0);
}
public int getSize(){
return map.size();
}
}
您的HashCode错误。
应该用小写形式。
public int hashCode()
为了确保该方法被覆盖,请使用@Override批注。
Pattern#HashCode
中的问题完全有可能。
第一个问题是它没有被使用(应该是Pattern#hashCode
),第二个问题是它没有计算出您认为的含义。
您可能会发现java.util.Arrays#hashCode
非常有用,将数组的支持从数组更改为List
也将起作用。
附带说明一下, Pattern
不是该类名称的理想选择,因为它与java.util.regex.Pattern
冲突。 在这种情况下,与其他情况相比,这更是一个问题,因为它可以与Scanner
一起使用。
正如另一个答案所指出的,要做的第一件事是重命名并注释您的hashcode()方法。
然后,您还必须修复它。 它用
char[] a = pattern;
return a.hashCode();
这意味着它使用char[]
对象的hashCode()
函数。 但是该函数直接从Object
继承,并为两个相等的字符数组提供了不同的哈希码。 例如,尝试以下操作:
char[] c = { 'a','b','c' };
char[] d = { 'a','b','c' };
System.out.printf("%d %d%n", c.hashCode(), d.hashCode());
您会看到它打印两个不同的数字。
因此,您需要使用更好的哈希码功能。 您可以自己制作,也可以使用Arrays.hashCode(pattern)
(不需要在本地a
变量)。 重要的是,当两个模式根据equals()
方法equals()
,它们应该具有相同的哈希码。
在这种情况下,您会通过测试所有输入键的相等性来查找HashCode(我将在一分钟内完成,这是一件坏事),所以equals
告诉您您在输入键中具有相同的键哈希图。 但是哈希图本身使用get()
的hashCode()
方法来定位对象。 根据hashCode()
方法,哈希图中没有具有相同键的对象!
因此,当对象相等时,它们必须始终保持一致。
现在,至于您查找对象的方法:
boolean contains = false;
for (Entry<Pattern, Integer> entry : map.entrySet())
{
Pattern patt = entry.getKey();
if ( p.equals(patt) ){
contains = true;
}
}
if ( contains ){
int time = map.get(p);
time++;
map.put(p, time);
} else
map.put(p, 0);
这不是您使用Map
。 HashMap
的全部要点是,您可以查看它是否在O(1)中包含某个键。 您正在做的是对其进行迭代并进行比较-这是O(N),非常浪费。
如果正确实现hashCode()
,则可以通过执行map.containsKey(p)
而不是该循环来查找它。 而且,如果确定没有在映射中放入空值,则可以简单地使用get()
来获取模式:
Integer time = map.get(p);
if ( time == null ) {
map.put( p, 0 );
} else {
map.put( p, time+1);
}
(您无需使用++
,因为将其放入地图后实际上并未使用time
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.