Should I care about no_entry_value in trove4j? - java

I'm using trove4j for its primitives collections. I notice it has constructors like
public TLongArrayList( int capacity, long no_entry_value )
where no_entry_value represents null. The default value is zero.
The null value in collections, like Set specially, is very important, according to my cognition. But I found trove4j did't use this value much after I glanced at the source code.
So I'm confused that should I care about that value. Should I elaborately pick a value that would never occur in my programs, or just leave it to be default zero.

This is kind of one of those things that you know you need when you need it. It comes down to whether or not you want to just call get(...) and know whether or not the value was in the map without calling containsKey(...). That's where the "no entry value" comes in because that is what is returned in the case where you didn't store that key in your map. The default is 0, so if you never store a value of 0 in your map, that will work for checks. But of course that can be a bit risky. Typical values would be 0, -1, Integer.MAX_VALUE... things like that.
If there is no value that you can guarantee will never be in your map, then you need to make sure you check with containsKey before you trust the returned value. You can minimize the overhead of doing two lookups with something like:
int value = my_map.get( my_key );
// NOTE: Assuming no entry value of 0
if ( value == 0 && !my_map.containsKey( my_key ) ) {
// value wasn't present
}
else {
// value was present
}
That's a performance improvement over calling containsKey every time before doing a get.

Related

about java recursion to create combination of string

The question was asking me to return set containing all the possible combination of strings made up of "cc" and "ddd" for given length n.
so for example if the length given was 5 then set would include "ccddd" and "dddcc".
and length 6 would return set containing "cccccc","dddddd"
and length 7 would return set contating "ccdddcc","dddcccc","ccccddd"
and length 12 will return 12 different combination and so on
However, set returned is empty.
Can you please help?
"Please understand extremeply poor coding style"
public static Set<String> set = new HashSet<String>();
public static Set<String> generateset(int n) {
String s = strings(n,n,"");
return set; // change this
}
public static String strings(int n,int size, String s){
if(n == 3){
s = s + ("cc");
return "";}
if(n == 2){
s = s + ("ddd");
return "";}
if(s.length() == size)
set.add(s);
return strings(n-3,size,s) + strings(n-2,size,s);
}
I think you'll need to rethink your approach. This is not an easy problem, so if you're extremely new to Java (and not extremely familiar with other programming languages), you may want to try some easier problems involving sets, lists, or other collections, before you tackle something like this.
Assuming you want to try it anyway: recursive problems like this require very clear thinking about how you want to accomplish the task. I think you have a general idea, but it needs to be much clearer. Here's how I would approach the problem:
(1) You want a method that returns a list (or set) of strings of length N. Your recursive method returns a single String, and as far as I can tell, you don't have a clear definition of what the resulting string is. (Clear definitions are very important in programming, but probably even more so when solving a complex recursive problem.)
(2) The strings will either begin with "cc" or "ddd". Thus, to form your resulting list, you need to:
(2a) Find all strings of length N-2. This is where you need a recursive call to get all strings of that length. Go through all strings in that list, and add "cc" to the front of each string.
(2b) Similarly, find all strings of length N-3 with a recursive call; go through all the strings in that list, and add "ddd" to the front.
(2c) The resulting list will be all the strings from steps (2a) and (2b).
(3) You need base cases. If N is 0 or 1, the resulting list will be empty. If N==2, it will have just one string, "cc"; if N==3, it will have just one string, "ddd".
You can use a Set instead of a list if you want, since the order won't matter.
Note that it's a bad idea to use a global list or set to hold the results. When a method is calling itself recursively, and every invocation of the method touches the same list or set, you will go insane trying to get everything to work. It's much easier if you let each recursive invocation hold its own local list with the results. Edit: This needs to be clarified. Using a global (i.e. instance field that is shared by all recursive invocations) collection to hold the final results is OK. But the approach I've outlined above involves a lot of intermediate results--i.e. if you want to find all strings whose length is 8, you will also be finding strings whose length is 6, 5, 4, ...; using a global to hold all of those would be painful.
The answer to why set is returned empty is simply follow the logic. Say you execute generateset(5); which will execute strings(5,5,"");:
First iteration strings(5,5,""); : (s.length() == size) is false hence nothing added to set
Second iteration strings(2,5,""); : (n == 2) is true, hence nothing added to set
Third iteration strings(3,5,""); : (n == 3) is true, hence nothing added
to set
So set remains un changed.

TObjectIntMap.get() returns 0 if null Trove

I am using trove library to create hash maps
http://trove.starlight-systems.com/
The class I am using is TObjectIntMap in which I had to use the function get.
The issue is that get returns 0 if two cases
1- If the value of the specified key is zero
2- If the key does not exist
For example in the following code
TObjectIntMap<String> featuresMap = new TObjectIntHashMap<String>();
if(String.valueOf(featuresMap.get("B")) == null)
System.out.println("NULL");
else
System.out.println("NotNull");
System.out.println(featuresMap.get("B"));
The program will print the following
1- NotNull: because it gets zero. Although the key "B" has not been set
2- Zero: The return of featuresMap.get("B") is zero instead of null.
I have checked their documentation in the link below and it was a mistake that they solved. So get actually return zero instead of null because int cannot be null.
https://bitbucket.org/robeden/trove/issue/43/incorrect-javadoc-for-tobjectintmapget
Now my question is: How to differentiate between a zero and Null in this case. Is their any way around to address this issue.
Try their containsKey method. If the value comes back 0, use that method to check if the map contains the key - if it does, then the key's value really is 0. If it doesn't, then the key is not set.

Single variable to represent either one item, all items, or none

I'm writing a method that accepts a UUID to represent items in an XML. What's the best way to special-purpose a value that represents "all" or "none"? I think it may be best not to make up UUIDs to represent all or none. Would I be better off creating a wrapper class that contains private variable flags for all or none?
You could use an enum like,
enum SelectionType {
ONE, ALL, NONE;
}
I think the cleanest implementation would be an array (or List) of UUIDs. However this assumes you actually know "all" of the UUIDs. "None"is covered. For "all", if you don't know all the UUIDs, have null be a special case, or else use a special constant. e.g.
public static final UUID[] ALL = new UUID[0];
And in your code
if (inArray == ALL)
handleAllCase();
else
onlyHandleUUIDsInArray(inArray);
Another possibility would be a range of UUIDs, with min and max. If max equals min it means "one", if max less than min it means "none", and for all you set min to the smallest possible UUID and max to the maximum.
Finally, a quick and dirty, but understandable approach might be to use null for none and a special value like "*" for all.

How do I use ArrayList<Integer>#contains when I only have a BigInteger?

I am pulling data values from a database that returns a List of <Integer>. However, I would like to see if the List contains my BigInteger. Is there a simple way to do this?
I currently have the following code in Java:
ArrayList<Integer> arr = new ArrayList<Integer>() {{add(new Integer(29415));}};
boolean contains = arr.contains(29415); // true
boolean contains2 = arr.contains(new BigInteger("29415")); // false
I'm not sure on an efficient way to do this?
The correct answer will be returned by evaluation of the following:
val != null
&& BigInteger.valueOf(Integer.MIN_VALUE).compareTo(val) < 0
&& BigInteger.valueOf(Integer.MAX_VALUE).compareTo(val) > 0
&& list.contains(val.intValue())
This will correctly solve the question of whether the BigInteger you have is "contained" within the List<Integer>. Note that here we only downcast where necessary. If the val is outside the range of Integer values there is no need to downcast as we know that the value cannot be within the list.
A more relevant question is whether you should actually be using a List<BigInteger> in place of a List<Integer> but that is a different question and not part of the answer to your explicit question
While arshajii provides a solution which works, i would vote against it.
You should never downcast values. You are running in danger of your program producing larger values which translate to invalid values when downcasted. This kind of bug will be super nasty to troubleshoot months later.
If your code works with BigInteger, then you should convert all values from the database into BigInteger. This is an upcast where you cannot loose values.
Overall I would value correctness over efficiency. If at all, I would reconsider your usage of BigInteger (maybe long is fine?) but because you have it, I assume you have a reason for it.
In Java List.contains() uses the equals() method internally and because BigInteger.equals(Integer) returns false, your List.contains() also returns false. Either use the an List<BigInteger> or extract the Int value from BigInteger (as arshajii explained!). Of course, if you really want to search effectively, you should think of a binary search (in a sorted list) or of another data structure like Map.
You can try using BigInteger#intValue():
arr.contains(myBigInteger.intValue())
Note, however, that if myBigInteger is too big to fit into an int, then only the lower 32 bits will be returned (as described in the linked docs). Therefore, you might want to check if myBigInteger is less than or equal to Integer.MAX_VALUE before checking for containment.

Create an almost unique identifier based on a given array of numbers

Given an array of numbers, I would like to create a number identifier that represents that combination as unique as possible.
For example:
int[] inputNumbers = { 543, 134, 998 };
int identifier = createIdentifier(inputNumbers);
System.out.println( identifier );
Output:
4532464234
-The returned number must be as unique as possible
-Ordering of the elements must influence the result
-The algorithm must return always the same result from the same input array
-The algorithm must be as fast as possible to be used alot in 'for' loops
The purpose of this algorithm, is to create a small value to be stored in a DB, and to be easily comparable. It is nothing critical so it's acceptable that some arrays of numbers return the same value, but that cases must be rare.
Can you suggest a good way to accomplish this?
The standard ( Java 7 ) implementation of Arrays.hashCode(int[]) has the required properties. It is implemented thus:
2938 public static int hashCode(int a[]) {
2939 if (a == null)
2940 return 0;
2941
2942 int result = 1;
2943 for (int element : a)
2944 result = 31 * result + element;
2945
2946 return result;
2947 }
As you can see, the implementation is fast, and the result depends on the order of the elements as well as the element values.
If there is a requirement that the hash values are the same across all Java platforms, I think you can rely on that being satisfied. The javadoc says that the method will return a value that is that same as you get when calling List<Integer>.hashcode() on an equivalent list. And the formula for that hashcode is specified.
Have a look at Arrays.hashCode(int[]), it is doing exactly this.
documentation
What you're looking for is the array's hash code.
int hash = Arrays.hashCode(new int[]{1, 2, 3, 4});
See also the Java API
I also say you are looking for some kind of hash function.
I don't know how much you will rely on point 3 The algorithm must return always the same result from the same input array, but this depends on the JVM implementation.
So depending on your use case you might run into some trouble (The solution then would be to use a extern hash library).
For further information take a look at this SO question: Java, Object.hashCode() result constant across all JVMs/Systems?
EDIT
I just read you want to store the values in a DB. In that case I would recommend you to use a extern hasing library that is reliable and guaranteed to yield the same value every time it is invoked. Otherwise you would have to re-hash your whole DB every time you start your application, to have it in a consistent state.
EDIT2
Since you are using only plain ints the hash value should be the same every time. As #Stephen C showed in his answer.

Categories