Java图片隐写校验中HashMap取值为null及hashCode重写疑问
Hey there, let's dig into why you're getting null for receiverHash in your check method—no need to mess with overriding equals() or hashCode() for Strings, since Java's String class already handles those correctly! The issue is almost certainly related to how you're handling the path keys or the HashMap instance itself.
What's Causing the Null Value?
First, let's rule out the obvious:
- Mismatched Path Strings: The
image.getPath()you use to store the hash might not be identical to thepathparameter you pass during validation. Common culprits include:- Case differences (Windows paths are case-insensitive, but
String.equals()is not—e.g.,"C:/Photo.jpg"vs"c:/photo.jpg") - Path separator discrepancies (
/vs\\on Windows) - Relative vs absolute paths (storing a relative path but validating with an absolute one, or vice versa)
- Invisible characters or trailing spaces in the path string
- Case differences (Windows paths are case-insensitive, but
- Different HashMap Instances: The
receiver.getMap()you use to store hashes might not be the exact same Map instance you're accessing during validation. If yourreceiverobject is reinitialized somewhere, the Map will be empty.
Step-by-Step Fixes
1. Standardize Path Strings to Eliminate Mismatches
Normalize your paths to a consistent format before storing and validating. Use File.getCanonicalPath() to resolve relative paths, standardize separators, and handle case differences on Windows:
// When storing the hash try { String normalizedPath = new File(image.getPath()).getCanonicalPath(); receiver.getMap().put(normalizedPath, this.hashTheImage(imageBytes)); // Optional: Debug output to confirm the stored path System.out.println("Stored path: '" + normalizedPath + "'"); } catch (IOException e) { e.printStackTrace(); // Handle path resolution failure (e.g., invalid path) } // Updated validation method private boolean checkForChanges(String path, String newlyGeneratedHash){ try { String normalizedPath = new File(path).getCanonicalPath(); // Optional: Debug output to confirm the checked path System.out.println("Checked path: '" + normalizedPath + "'"); String receiverHash = receiver.getMap().get(normalizedPath); if(receiverHash == null) { JOptionPane.showMessageDialog(new JFrame(), "No hash record found for this image!", "ERROR!", JOptionPane.ERROR_MESSAGE); return false; } if(!newlyGeneratedHash.equals(receiverHash)){ JOptionPane.showMessageDialog(new JFrame(), "Image has been edited!", "ERROR!", JOptionPane.ERROR_MESSAGE); return false; } return true; } catch (IOException e) { JOptionPane.showMessageDialog(new JFrame(), "Failed to resolve image path!", "ERROR!", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); return false; } }
2. Verify HashMap Instance Consistency
Make sure the Map you're storing hashes in is the same one you're reading from. Add quick debug prints to confirm:
// After storing a hash System.out.println("Total stored hashes: " + receiver.getMap().size()); // At the start of your check method System.out.println("Total available hashes for validation: " + receiver.getMap().size());
If the sizes don't match, your receiver object (or its Map) is being recreated somewhere in your code. You may need to use a singleton pattern, persist the Map to a file/database, or ensure receiver is passed consistently between components.
Extra Optimizations
- Handle Edge Cases: Add error handling for invalid paths or missing image files to avoid unexpected crashes.
- Persist Hashes: If your app needs to retain hash records across restarts, replace the in-memory
HashMapwith a persistent storage option like a local properties file or lightweight database.
内容的提问来源于stack exchange,提问作者ivaa14

