2

Not having any luck finding this, but I'm trying to override the String func in Java. I'm using given source code for a dictionary search, and how it works is it basically hashes all the words. It does it though so that "HI" and "hi" are not the same word. I figure the simplest way is to write my own hash function for String so that "hi" will then hash and reveal "Hi" in the dictionary. How do I do this?

1
  • Overriding String hashCode() will have not benefit unless you also override equals(). Changing both has the potential to break any code which uses String (which is most of the JDK) Commented Jun 21, 2011 at 8:02

4 Answers 4

4

You make a class with a single field, a String.

You @Override equals and hashCode on your class to do case-insensitive stuff.

You store objects of your class in a HashSet or HashTable or whatever.

Sign up to request clarification or add additional context in comments.

2 Comments

That's going to involve a LOT of code rewriting the way the example's written. Is there a way to just override String funcs for the program alone?
If you first refactor the code to remove all duplication related to using the map, then doing this should require changing only about three lines of code: create the map, put things in the map, take things out of the map.
4

Similar to @Oli's, but without having to call to...Case before calls

public class CaseInsensitiveMap<V> implements Map<String, V> {  

  private final Map<String, V> map;  

  public CaseInsensitiveMap(Map<String, V> map) {  
    this.map = map;  
  }  

  public V put(String key, V value) {  
    return map.put(key.toLowerCase(), value);  
  }  

   /// etc...
}  

3 Comments

This is wrong. Try "HI" after Locale.setDefault(new Locale("tr")). Search "infamous Turkish locale bug".
@bkail I think it is designed for latin alphabet already. If you set locale as tr, then yes HI and hı are the same things in case-insensitivity manner, and it still works. Where's the problem?
Whether or not get("hi") will work after put("HI", ...) depends on the locale. One fix would be toLowerCase(Locale.ENGLISH).
2

Call String.toUpperCase() before you run the hash function?

4 Comments

The way it works, it sees they're equal, then gets the string out of the hash table for the dictionary definition. So if I used String.toUpperCase to make the hash and everything equal, I'd end up having all my words in uppercase
@Jdban101 - If you're wanting case insensitivity in your hash, then you must have multiple capitalizations. Which one do you want? All of them?
@spinning_plate I want my hash to search "hi" and "HI" in the same place so that they can take the word "Hi" out of the database. The cases are not constant, words such as "DSL" are in the dictionary, as are words like "T1 Cable"
This is wrong. Try "hi" after Locale.setDefault(new Locale("tr")). Search "infamous Turkish locale bug".
1

The idea has three faults: it is bad, impossible and unnecessary.

It's impossible, because java.lang.String is final. You can't inherit from it, so you can not override any methods.

It's bad in two ways: firstly because you would change the contract and behaviour of one of the core classes. Being able to pass an instance of String that does not behave like String could break literally anything. Secondly, I understand that to do what you want you would have to override equals as well - and this would end with an asymmetric equals (where a.equals(b) != b.equals(a) in case where one of a or b is a plain string and one your special version). I think case insensitive string being equal to an ordinary string was actually an example of a really bad idea in Bloch's "Effective Java".

It's unnecessary, because what you need is an object that holds a String and delegates to it. It could also have a constructor or a static factory method that takes a plain string. Or a case insensitive map, whatever. Plenty of examples in other answers.

3 Comments

Not impossible. You can supply your own version of the String class using Xbootclasspath. You could even use this to re-write hashing functions as the OP wants, providing the code isn't run in a secure environment (i.e. JNLP). However, this would be insanely bad practice and I agree, totally unnecessary.
@hoipolloi - "impossible" as in "it is not possible to access private attributes from outside their classes". Too much precision kills answers :-)
"it is not possible to access private attributes from outside their classes" - o rly? download.oracle.com/javase/1.4.2/docs/api/java/lang/reflect/… -> setAccessible ... just kidding, I know what you mean. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.