Can someone explain to me the usage of Integer, Boolean etc in place of their primitive types in JAVA?
I can't seem to grasp the advantages their are providing. They seem to create unnecessary problems of handling null values.
Thanks!
Boolean, Integer, Long, ... are Objects. You can use them in places where you can't use primitive types, e.g.
storing them in a Collection like a Map
using them as template parameter
assigning them a null value
using them in a more general way (e.g. Long as Number)
Examples:
new ArrayList<Integer>();
Long id = null;
Number num = new Long( 3 );
The rationale for Integer, Boolean, and so on is to allow primitive types to be used in contexts that require a reference type. The classic use-case is the collection APIs which provide sets, lists, maps, queues and so on where the element type must be some reference type.
Thus I can write:
List<Integer> list = new ArrayList<Integer>();
but the following is a compilation error:
List<int> list = new ArrayList<int>();
Note that this use-case for the primitive wrapper types predates both generic types and the "new" collections APIs, and goes back to the days where the only collection types were the original (pre-generic) forms of Vector and Hashtable, and their ilk.
Sometimes you really need a value to be nullable, for instance if your app stores user data, a social security # may be unknown. In that case it's cleaner to store null instead of -1.
Also there are things you can't do with primitive types, like storing them in a map or using polymorphism (Double and Integer both are instances of Number).
primitives are always faster.
however there are times, when objects are really useful:
1. upcasting. Your function can take Number(is a parent for all numeric objects: Integer, Float, etc.) for an argument.
2. Possible null value. For example it is used while storing in database. Object can be null, primitives must have value. So if field in db is nullable, it is better to use object version of primitive value.
3. if function takes object and you always give it a primitive there are expenses on autoboxing(turning primitive into object). The same for returning from function.
4. Objects have certain methods, such as getHashcode(), toString() etc., which can be really useful in some cases.
Related
Read this on the oracle docs java.lang page:
Frequently it is necessary to represent a value of primitive type as if it were an object. The wrapper classes Boolean, Character, Integer, Long, Float, and Double serve this purpose.
I'm not sure I understand why these are needed. It says they have useful functions such as equals(). But if I can do (a==b), why would I ever want to declare them as Integer, use more memory and use equals()? How does the memory usage differ for the 2?
Java's generics system only supports class types. And since primitives are not classes, they can't be used with generics. However, a primitive's wrapper class can be used as a generic type. For example, you may not declare an ArrayList<int>, but you can achieve a similar functionality with an ArrayList<Integer>.
It is also of occasional use to initialize a variable's value to null. Primitives, however, cannot be set to null; that privilege is reserved for objects.
// This is OK
Integer iDontKnowValueYet = null;
// Compile error!
int iDontKnowThisYetEither = null;
Things like int, char, double are all primitives meaning they do not need to be instantiated by using "new". Things like Integer, Character, Double are objects that take up more room on the computer (since there is more overhead for objects) but you can use methods like Integer.parse(). In general, use the primitives and only use the object versions if you need one of the methods.
To answer the thing about a==b vs a.equals(b):
Integer a = new Integer(5);
Integer b = new Integer(5);
Even though they are the same value (which is what .equals tests for) they are not the same piece of memory since you said "new" twice. a!=b but a.equals(b)
Integer a = new Integer(5);
Integer b = a;
Now they use the same piece of memory meaning if you change one, you change them both (unless you use "new" again). a==b and a.equals(b)
//using last code block
b = new Integer(5);
Now once again a!=b but a.equals(b)==true since once again they have the same value but they are on different pieces of memory.
Your ints are usually wrapped in wrapper classes when you put them in a data structure. So, .equals method is used to determine when you call .contains method on the data structure.
Other usefule methods:
toString
toHexString
parseString
I have a Hashtable which has a key of String and the value as String, but I've reached a point in my project where I need to be able to store multiple different data types. For example, I'm going to need to store int, String, Date, etc, all in one Hashtable.
HashTable or any Collection Map can handle this, except for int and other primitive types: you can't store primitive types, only Object references. int will need to be wrapped as a Integer object.
Map<String, Object> map = new HashMap<String, Object>()
This gives you a map with keys of type String and values of type Object, which basically means any descendant of type Object (Date, Integer, String etc.). Other answers correctly point to the fact that instead of using primitives such as int, boolean it is required to use their counterparts Integer, Boolean etc.
The return type of get operation on such map is Object. Thus, it is developer's responsibility to handle type information correctly.
A good answer to the question as to what is the difference between Hashtable and HashMap is provided here.
You can have it store the general data type Object, though that will not allow primitive data types.
While this is possible, it's generally not a good idea. More often than not this leads to type casting exceptions and problems.
The HashTable can be set to store generic Objects as opposed to specific class types, however the type conversion when retrieving them does not happen automatically.
In order to get the object back out of the collection, some form of type checking routines will have to be developed.
You're better off creating a separate collection for each class type you want to store.
PS: I would also recommend using a HashMap instead of HashTable. HashTable has been deprecated.
Change your HashTable to Hashtable<String, Object> and when you want to store an int you need to cast it first(or use autocast) to an Integer. After getting your value from the table you can determ your type by if(value instanceof String) and so on for any type.
I'm doing a project in Java in which I'm looking at the frequency characters occur after each other character in a text. When I'm collecting my results, I'm storing them in a 2d array of ints. However, in the same results table, I want to store some results about the whole thing.
Is it possible to have an array where some of the elements are arrays, and others are primitives?
Yes, you can have Object[] and store a mix a types, although it would have to be the wrapper Integer (not the primitive int). (Note: you could "cheat" and save each int as a single-element array int[], thus making it an Object, but "don't try this at home")
But even if you could, an array isn't the right approach. Instead, create a class for this.
Try something like this:
public class FrequencyAnalysis {
private int[] frequencies;
private String info;
private Date lastRun;
// etc
}
No, it is not working. There can only be objects OR primitives in one array. Anything else is just a workaround.
In that case you would have to store Objects (primitives will autobox to Wrapper classes) and then when you read the entries you would need to instanceof the Object and then cast it safely.
You can use boxed types, i.e. java.lang.Integer (So your array type must be Object[]), but better do make a new class for results Storage
In which case should you use primitive types(int) or reference types (Integer)?
This question sparked my curiosity.
In which case should you use primitive
types(int) or reference types
(Integer)?
As a rule of thumb, I will use a primitive (such as int) unless I have to use a class that wraps a primitive.
One of the cases were one must use a wrapper class such as Integer is in the case of using generics, as Java does not support the use of primitive types as type parameters:
List<int> intList = new ArrayList<int>(); // Not allowed.
List<Integer> integerList = new ArrayList<Integer>(); // Allowed.
And, in many cases, I will take advantage of autoboxing and unboxing, so I don't have to explicitly perform conversions from primitives to its wrapper class and vice versa:
// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3);
int sum = 0;
// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
sum += number;
}
Also, as an additional note, when converting from primitives to its wrapper class objects, and unique instances of objects are not necessary, use the valueOf method provided by the wrapper method, as it performs caching and return the same instance for a certain value, reducing the number of objects which are created:
Integer i1 = Integer.valueOf(1); // Prefer this.
Integer i2 = new Integer(1); // Avoid if not necessary.
For more information on the valueOf methods, the API specification for the Integer.valueOf method can serve as a reference for how those methods will behave in the wrapper classes for primitives.
That really depends on the context. First prefer the primitive, because it's more intuitive and has less overhead. If it is not possible for generics/autoboxing reasons, or if you want it to be nullable, then go for the wrapper type (complex type as you call it).
The general rules I follow when creating an API can be summarized as follows:
If the method must return an value, use a primitive type
If the method may not always apply (eg: getRadioId(...) on an object where such an ID may not exist), then return an Integer and specify in the JavaDocs that the method will return null in some cases.
On #2, look out for NPEs when autoboxing. If you have a method defined as:
public Integer getValue();
And then call it as follows:
int myValue = getValue();
In the case where getValue() returns null you'll get an NPE without an obvious cause.
Since Java does something called auto-boxing and auto-unboxing, you should use the primitive type int in most cases because of less overhead.
The only time you absolutely need to use Integer is in generics.
List<int> list; // won't compile
List<Integer> list; // correct
One case in which Integer might be prefered is when you are working with a database where numerical entries are allowed to be null, since you wouldn't be able to represent a null value with an int.
But of course if you're doing straight math, then int would be better as others have mentioned due to intuitiveness and less overhead.
My rule of thumb is: use boxed primitives only when it's necessary to get the code to compile. The only places in your code where the names of the primitive wrapper classes should appear is in generic type parameters and static method calls:
List<Integer> intList = new ArrayList<Integer>();
int n = Integer.parseInt("123");
That's the advice I would give to new Java programmers. As they learn more, they'll run into situations where they have to be more discerning, like when dealing with Maps or databases, but by then they should also have a better understanding of the difference between primitives and boxed primitives.
Autoboxing tempts us to believe int and Integer (for example) are interchangeable, but it's a trap. If you mix the two kinds of value indiscriminately, you can end up comparing two Integer values with == or trying to unbox a null without realizing it. The resulting bugs can be intermittent and difficult to track down.
It doesn't help that comparing boxed primitives with == sometimes works as if it were doing a value comparison. It's an illusion caused by the fact that values within a certain range are automatically cached in the process of autoboxing. It's the same problem we've always had with String values: comparing them with == sometimes "works" because you're actually comparing two references to the same, cached object.
When dealing with strings we can just tell the n00bs never to compare them with ==, as we've been doing all along. But comparing primitives with == is perfectly valid; the trick (thanks to autoboxing) is being sure the values really are primitives. The compiler will now let us declare a variable as an Integer and use it as if it were an int; that means we have to exercise a greater level of discipline and treat it as an error when someone does so without good reason.
Rather than calling them "complex types", you'd be best served thinking Integer, Double, etc. as "Classes", and int, double, etc. as "primitives".
If you're doing any type of sophisticated math, the Class-based numeric representation like Integer and Double will be cumbersome and slow you down - many math operations can only be done with primitives.
On the other hand, if you're trying to put your numbers into collections like Lists and Maps, those collections can only contain objects - and thus you must use (or convert to) classes like Integer and Double.
Personally, I use primitives whenever I can get away with it, and only convert to the Class representations like Integer when it's time to do input or output, and the transport requires those representations.
However, if you aren't doing any math at all, and instead are just passing the values straight through your code, you might save yourself some trouble by dealing with the Class-based forms (like Integer) exclusively.
I think this is a bit late but I wanted to add my opinion just in case.
in some scenarios, it's required to use the wrappers as the lack of a value is different from the default value.
example,
for one project I worked on, there was a field on screen where the user could enter a double value, the business requirement clearly mentioned that if the user enters a 0 the meaning is different from not entering a value and leaving the field blank and this difference will make an impact later on in a different module.
so in this scenario we had to use the Double object, since I cannot represent a lack of value using the primitive; since the primitive will default to 0 which was a valid input for the field.
I dont think there is any rule as such. I would choose the types over primitives (Integer over int) when I write method signatures, Maps, collections, Data Objects that get passed around. As such I would still like to use Integer instead of int even inside of methods etc. But if you think that is too much trouble (to type extra "eger") then it is okay to use ints for local variables.
If you want to setAttribute to session you have to use Object like Integer,Boolean,String in servlets. If you want to use value you can use primitive types. Objects may be null but primitives not. And if you want to compare types for primitives use == but objects use .equals because in object comparision == looks not values it looks if these are the same objects. And using primitives makes faster the code.
When we deal with Spring getRequest mapping methods, using boolean value does not work.
For instance :
#GetMapping("/goal")
public boolean isValidGoal() {
boolean isValid = true;
return isValid;
}
Always opt for Boolean in those cases.
I have heard of types being referred to as "boxed" in some languages.
In Java, I have heard of "autoboxing". What is this? Is it having wrapper classes for a type? How would my code change if I'm working with boxed or unboxed types?
Some data types are considered "primitive", meaning they are not treated like an object and don't have the properties of an object.
On most platforms, integers and characters are examples of types that are primitive but can be boxed.
Boxing means wrapping them in an object so they have the behavior of an object.
The exact meaning and behavior depends on the language you're using. Some languages (such as Smalltalk... at least waaay back when I was doing it...) don't allow any primitive types and consider everything to be an object, but there's a performance penalty associated with that because, at the end of the day, the processor needs to work with raw numbers and raw memory to do useful work. If you want to add two integers that have been boxed, for example, behind the scenes they are "unboxed" into primitive types, the numbers are added, and they are then boxed back into a new integer.
More specific information for Java:
Autoboxing allows java to automatically convert things like boolean and int to their Object versions Boolean and Integer in most cases. It also allows the reverse to happen.
For example:
int a = 3; // no boxing is happening
Integer b = 3; // newer versions of java automatically convert the int 3 to Integer 3
int c = b; // these same versions also automatically convert Integer 3 to int 3
Older versions of java that do not have autoboxing will require this code to do the same thing:
int a = 3; // works the same
Integer b = new Integer(3); //must set up a Integer object manually
int c = b.intValue(); //must change Integer object to a primitive
However, there are some scenarios where you still have to do things manually. For example, imagine you have a class with two methods like so:
assertEquals(int a, int b);
assertEquals(Object a, Object b)
Now, if you try to do this:
Integer a = 3;
int b = 3;
assertEquals(a, b); // this will not compile
The reason this doesn't work is because it cannot figure out whether it should unbox a to an int or box b to an Integer. Therefore it is ambiguous which method signature should be called. To fix this you can do one of these:
assertEquals((int) a, b);
assertEquals(a, (Integer) b);
Yes, boxing means taking a value type and wrapping it in a reference type. Since java introduced autoboxing you can do:
void foo(Object bar) {}
//...
foo(1);
And java will automatically turn the int 1 into an Integer. In previous versions you'd have to do:
foo(new Integer(1));
Autoboxing is most useful in java when working with generics, since you can't use primitives with generics, so to store ints in a list, you'd have to make a List<Integer> and put the ints into the list boxed.
A boxed type means that the values are allocated in a block on the heap and referenced through a pointer. This is good for uniformity in the implementation of the runtime (it makes it easier to have generic functions, etc), at the cost of an additional indirection.
Generally when you work with collections, you're dealing with arrays of Objects. In languages like Java, there is a difference between a primitive and an Object. When a primitive is "boxed", it's essentially just a wrapper around a primitive so it plays nice with the rest of the framework that's expecting an Object.
Autoboxing is just the act of putting a primitive into an object or pulling a primitive out of an object transparently so you don't have to worry about the extra step of doing it yourself.
Boxed means that they took a regular value type and created an object around it. Sort of like putting it in a box. This is generally to be avoided, because of the overhead of constructing the object.