As a primitive version of Optional*, Java 1.8 provides OptionalInt, OptionalLong and OptionalDouble.
But I cannot find the equivalent OptionalBoolean class.
Are there any technical reasons against having an OptionalBoolean?
*
An Optional may or may not have the presence of a value, is used as an alternative to null.
This quote explains the considerations behind having primitive streams. I'm assuming the same applied to primitive Optionals. In short, primitive streams (and probably Optionals as well) were created for performance reasons. They didn't create them for all 8 primitive types to reduce code duplication and interface pollution.
Quoting the words of Brian Goetz in the lambda mailing list:
More generally: the philosophy behind having specialized
primitive streams (e.g., IntStream) is fraught with nasty tradeoffs.
On the one hand, it's lots of ugly code duplication, interface
pollution, etc. On the other hand, any kind of arithmetic on boxed ops
sucks, and having no story for reducing over ints would be terrible.
So we're in a tough corner, and we're trying to not make it worse.
Trick #1 for not making it worse is: we're not doing all eight
primitive types. We're doing int, long, and double; all the others
could be simulated by these. Arguably we could get rid of int too, but
we don't think most Java developers are ready for that. Yes, there
will be calls for Character, and the answer is "stick it in an int."
(Each specialization is projected to ~100K to the JRE footprint.)
Trick #2 is: we're using primitive streams to expose things that are best done in the primitive domain (sorting, reduction) but not
trying to duplicate everything you can do in the boxed domain. For
example, there's no IntStream.into(), as Aleksey points out. (If there
were, the next question(s) would be "Where is IntCollection?
IntArrayList? IntConcurrentSkipListMap?) The intention is many streams
may start as reference streams and end up as primitive streams, but
not vice versa. That's OK, and that reduces the number of conversions
needed (e.g., no overload of map for int -> T, no specialization of
Function for int -> T, etc.)
And I should mention that I found that quote in the answer to this question.
boolean values are often abused as parameters. Effective Java 2nd edition warns against abuse of booleans. They often lead to badly readable code if they are not for actual boolean true/false arguments. Instead, Joshua Bloch - the writer - tries to convince people to use double valued enum's:
Prefer two-element enum types to boolean parameters. It makes your code easier to read and to write, especially if you're using an IDE that supports autocompletion. Also it makes it easy to add more options later.
Most OptionalBoolean instances would probably be used incorrectly. This is a good reason for not including one. But I cannot say - only Oracle can - if this is the reason why it is not in there.
Apart for the desire to reduce the magnitude of the combinatorial explosion of primitive type specialisation classes I suspect one major reason for the absence of an OptionalBoolean is that the advantage of such a class is much smaller than the advantage of specialisations for the numeric types.
The reason for why the advantage is smaller is that there are only two different values of the type boolean. Because of this, most of the time you only get two object of type Boolean. Those two are cached as Boolean.TRUE and Boolean.FALSE and reused in most cases, e.g. when booleans are auto-boxed. Numeric wrapper types have a number of cached objects for a small range of values, for other values a new object has to be allocated every time a primitive value is stored in a generic container such as Optional.
So an Optional<Boolean> object is almost as efficient as an OptionalBoolean would be since no new Boolean have to be allocated to put an unboxed boolean into it.
I could also be useful to have two cashed Optional<Boolean> available somewhere in the standard library, as Optional.TRUE/FALSE perhaps. I don't know the reason for why there isn't.
Just to be complete about that: There is indeed an OptionalBoolean in Java 8, but not where you would expect it: it is com.sun.javafx.scene.control.behavior.OptionalBoolean.
But, while JavaFX is nowadays a fixed component of Java, it is not advisable to use it outside of JavaFX stuff.
Apart from that, its interface is completely different from the ones you have in java.util.*.
Related
Java does not allow primitive types to be used in generic data structures. E.g. ArrayList<int> is not allowed. The reason is, primitive types can not be directly converted to Object. However Java 1.5 does support auto-boxing, and wrapper classes work in generic data structures. So why couldn't the compiler auto-box it to ArrayList<Integer>? Are there any other reasons for why this can not work?
So as far as I understand it, your proposed ArrayList<int> would be identical to ArrayList<Integer>. Is that right? (In other words, internally it still stores an Integer; and every time you put something in or get it out, it would automatically box/unbox it, but autoboxing/autounboxing already does that for ArrayList<Integer>.)
If it is the same, then I don't understand what the utility of having a duplicate syntax <int> is when it means the same thing as <Integer>. (In fact it will introduce additional problems, because for example int[] is not the same runtime type as Integer[], so if you have T[], and T is int, what would it mean?)
The generic type information is erased at run time. Check this link. Generics have more to do with compile time checking than run time checking. The autoboxing and unboxing are the run time operations. See the link. This is the reason that autoboxing should not work with Generics.
The problem will be in performance. For every get()/set() method, in the list, the JVM will have to unbox/box the respective value for the mentioned method respectively. Remember, autoboxing take primitive types and wraps them into an Object and vice-versa, as stated on Autoboxing:
Finally, there are performance costs associated with boxing and
unboxing, even if it is done automatically.
I think they wanted a List to do simple operation and alleviating performance all together.
I don't think there's any technical reason it couldn't be done like you say, but there are always interface considerations: e.g., if you automatically converted objects of type ArrayList<int> to be ArrayList<Integer>, you lose some explicitness in terms of the interface specifications: it is less obvious that ArrayList in fact store objects, not primitives.
My understanding is that autoboxing is more for compatibility and flexibility in parameter types than for the ease of being able to say "int" instead of "Integer." Java's not exactly known for it's obsession with conciseness...
A small P.S.: I don't think it would technically be correct to say "autobox ArrayLint<int> to ArrayList<Integer>," because you aren't actually wrapping anything in an object "box" -- you're just actually converting a typename ArrayList<int> to "actual" type ArrayList<Integer>
I'm glad it is impossible, because int use much less memory than Integer and is much faster too. Therefore it forces me to think whether it is acceptable to use Collection<Integer> or not (lot of times in business application it's ok, but in other apps it is not).
I would be much happier if Collection<int> was possible and efficient, but it is not.
I don't think this is any sort of problem - do you have any concrete case where is this limiting you somehow? And btw there is difference between int and Integer while the object can be null and primitive type can't.
I am confused about when to use primitive vs. non-primitive(?) types (i.e. int vs. Integer) in Java. I realize that in some places you can't use primitive types (for example when making use of generics). But what about in "normal" code? Is there a performance penalty for using non-primitive types? What about when working with Android?
***My question is very similar to this question, which was discovered by one of the posters below. The answers to the linked question give additional insights into this question, which are not covered below.
*** "non-primitive" types are officially referred to as reference types.
Short answer: An int is a number; an Integer is a pointer that can reference an object that contains a number. Using Integer for arithmetic involves more CPU cycles and consumes more memory. An int is not an object and cannot passed to any method that requires objects (just like what you said about Generics).
Non-primitive types are objects. They have to be dynamically allocated, garbage collected, and checked for null-ness (although some of these operations may get removed by an optimizing compiler). Reading their actual value requires loading from a pointer. Primitive types are values. They generally take up less space and are faster to access.
A good rule of thumb is, use primitive types unless you need polymorphism, in which case use the corresponding object.
There is a slight penalty for converting between the types (autoboxing). Also int will have a bit less overhead so I would always go with int if you can.
Also see this question: When to use primitive and when reference types in Java
In Java, int is a primitive data type, while Integer is a Wrapper class.
int, being a primitive data type has less flexibility. We can only store the binary value of an integer in it.
Since Integer is a wrapper class for int data type, it gives us more flexibility in storing, converting and manipulating integer data.
Integer is a class and thus it can call various in-built methods defined in the class. Variables of type Integer store references to Integer objects, just as with any other reference (object) type.
You can find a more detailed explanation here.
As an OO purist, you would likely shun the primitives altogether and damn the performance costs and lack of postfix operators. (Yes, there is a performance cost.) You may also adopt this approach simply from extensibility considerations as a designer (without necessarily being hung up on purity.)
As a practical matter (outside of theoretical and aesthetic questions), use the primitives everywhere you can and use the object version where you can't use primitives. (You already mentioned one such case. The language and APIs will drive this decision.)
As a performance freak, you would likely shun the object versions and you may not really care too deeply if you step on a few OO golden rules and sacrosanct no-goes: performance is king and you make your decisions accordingly.
I'd recommend option 2 as a good place to start until you develop your own dogmatic preferences! :)
My view: Using Integer as parameters or return values allows one thing that primitive ints don't allow: Using null. But is this a good idea? I think it rarely ever is.
As far as performance is concerned: The compiler will optimize your code to some degree, so that is most of the time not a real concern.
In the way of learning Java Generics, I got stuck at a point.
It was written "Java Generics works only with Objects and not the primitive types".
e.g
Gen<Integer> gen=new Gen<Integer>(88); // Works Fine ..
But, with the primitive types like int,char etc ...
Gen<int> gen=new Gen<int>(88) ; // Why this results in compile time error
I mean to say, since java generics does have the auto-boxing & unboxing feature, then why this feature cannot be applied when we declare a specific type for our class ?
I mean, why Gen<int> doesn't
automatically get converted to
Gen<Integer> ?
Please help me clearing this doubt.
Thanks.
Autoboxing doesn't say that you can use int instead of Integer. Autoboxing automates the process of boxing and unboxing. E.g. If I need to store some primitive int to a collection, I don't need to create the wrpper object manually. Its been taken care by Java compiler. In the above example you are instantiating an generic object which is of Integer type. This generic object will still work fine with int but declaring int as a generic type is wrong. Generics allow only object references not the primitives.
As you have discovered, you can't mention a primitive type as a type parameter in Java generics. Why is this the case? It is discussed at length in many places, including Java bug 4487555.
The simple explanation: Generics are defined that way.
A good reason from the Java perspective: It simplifies type erasure and translation to byte code for the compiler. All the compiler needs to do is some casting.
With non-primitives the compiler would have to decide whether to cast or to inbox/outbox, it would to need to have additional validating rules (extends and & wouldn't make sense with primitives, should a ? include primitives, yes or no? and so on) and have to handle type conversions (assume you parametize a collection with long and add an int...?)
A good reason from a programmers perspective: operations with a bad performance are kept visible! Allowing primitves as Type Arguments would require hidden autoboxing (inboxing for store, outboxing for read operations. Inboxing may create new objects which is expensive. People would expect fast operations if they parametize a generic class with primitives but the opposite would be true.
That's a very good question.
As you suspected, the abstraction could surely be extended to the type parameters, and made them trasparent to the programmer. In fact, that is what most modern JVM languages do (statically typed ones, of course). Examples include Scala, Ceylon, Kotlin etc.
This is what your example would look like in Scala:
val gen: Gen[Int] = new Gen[Int](80)
Int is just a regular class, just like other classes. There is no primitive-object distinction whatsoever.
As to why Java people did not do it... I don't actually know the reason, but I imagine such an abstraction would not fit with the existing Java specification without overcomplicating the semantics (or without sacrificing the backward compatibility, which is certainly not a viable option).
Java collections only store Objects, not primitive types; however we can store the wrapper classes.
Why this constraint?
It was a Java design decision, and one that some consider a mistake. Containers want Objects and primitives don't derive from Object.
This is one place that .NET designers learned from the JVM and implemented value types and generics such that boxing is eliminated in many cases. In CLR, generic containers can store value types as part of the underlying container structure.
Java opted to add generic support 100% in the compiler without support from the JVM. The JVM being what it is, doesn't support a "non-object" object. Java generics allow you to pretend there is no wrapper, but you still pay the performance price of boxing. This is IMPORTANT for certain classes of programs.
Boxing is a technical compromise, and I feel it is implementation detail leaking into the language. Autoboxing is nice syntactic sugar, but is still a performance penalty. If anything, I'd like the compiler to warn me when it autoboxes. (For all I know, it may now, I wrote this answer in 2010).
A good explanation on SO about boxing: Why do some languages need Boxing and Unboxing?
And criticism of Java generics: Why do some claim that Java's implementation of generics is bad?
In Java's defense, it is easy to look backwards and criticize. The JVM has withstood the test of time, and is a good design in many respects.
Makes the implementation easier. Since Java primitives are not considered Objects, you would need to create a separate collection class for each of these primitives (no template code to share).
You can do that, of course, just see GNU Trove, Apache Commons Primitives or HPPC.
Unless you have really large collections, the overhead for the wrappers does not matter enough for people to care (and when you do have really large primitive collections, you might want to spend the effort to look at using/building a specialized data structure for them).
It's a combination of two facts:
Java primitive types are not reference types (e.g. an int is not an Object)
Java does generics using type-erasure of reference types (e.g. a List<?> is really a List<Object> at run-time)
Since both of these are true, generic Java collections can not store primitive types directly. For convenience, autoboxing is introduced to allow primitive types to be automatically boxed as reference types. Make no mistake about it, though, the collections are still storing object references regardless.
Could this have been avoided? Perhaps.
If an int is an Object, then there's no need for box types at all.
If generics aren't done using type-erasure, then primitives could've been used for type parameters.
There is the concept of auto-boxing and auto-unboxing. If you attempt to store an int in a List<Integer> the Java compiler will automatically convert it to an Integer.
Its not really a constraint is it?
Consider if you wanted to create a collection that stored primitive values. How would you write a collection that can store either int, or float or char? Most likely you will end up with multiple collections, so you will need an intlist and a charlist etc.
Taking advantage of the object oriented nature of Java when you write a collection class it can store any object so you need only one collection class. This idea, polymorphism, is very powerful and greatly simplifies the design of libraries.
The main reason is the java design strategy.
++
1) collections requires objects for manipulation and primitives are not derived from object
so this can be the other reason.
2) Java primitive data types are not reference type for ex. int is not an object.
To Overcome:-
we have concept of auto-boxing and auto-unboxing. so if you are trying to store primitive data types compiler will automatically convert that into object of that primitive data class.
I think we might see progress in this space in the JDK possibly in Java 10 based on this JEP - http://openjdk.java.net/jeps/218.
If you want to avoid boxing primitives in collections today, there are several third party alternatives. In addition to the previously mentioned third party options there is also Eclipse Collections, FastUtil and Koloboke.
A comparison of primitive maps was also published a while ago with the title: Large HashMap overview: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove. The GS Collections (Goldman Sachs) library was migrated to the Eclipse Foundation and is now Eclipse Collections.
Actually here is a similar topic with little practical value.
As far as I understand, primitives perform better and should be used everywhere except for the cases where Object-related features (e.g. null check) are needed. Right?
Do not forget that, since creating a new wrapper for every boxing occurrence is quite expensive, especially considering it usually being used at a single scope of a method, Autoboxing uses a pool of common wrappers.
This is in fact an implementation of the flyweight design pattern. When a boxing occurs for a well-known value, instead of creating a new wrapper instance, a pre-created instance is fetched from a pool and returned.
One consequence is: it’s still not recommended to use autoboxing for scientific calculations. For example, the code d = a * b + c is using Integer classes for a, b, c and d, and the generated code is d.valueOf(a.intValue() * b.intValue() + c.intValue()). All these method invocations have their own overhead, so it’s usually recommended to use autoboxing when needed to store primitives in collections.
And even then, if you have a huge collection of Integer wrapping int, the overhead can implies longer execution times, up to 20 times longer, as reported in this article.
Jb adds this important comment:
Also Wrapper.valueOf(primitive) uses pool of wrappers. So prefer Integer.valueOf(5) to new Integer(5)
Primitives are faster when they are used, as objects need to be unboxed before use; thus there is an extra step for the VM to perform. For example, In order perform arithmetic on an Integer, it must first be converted to an int before the arithmetic can be performed.
In many business applications this probably rarely matters. But if you were writing something very numnber-crunching heavy like, say, a graphics transformation processor you are a lot more likely to care.
yes, primitives are faster than objects.
Since java 5 you can even mix primitives and objects without manually converting one to another.
The autoboxing mechanism takes care of just that.
this means that if you put a primitive in a collection, the compiler will not complain, and convert the primitive to an object implicitly.
If you need store primitives in collections you might use commons-primitives.
I prefer using primitives to wrappers, only place that absolutely needs to have wrappers are entity classes. Databases support nulls, so entities should too.
I once worked on project that used primitives (and homebrew ORM) in database access:
class Foo{
int xxx = -1;
...
}
And then you had:
void persist(Foo foo){
...
statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX());
...
}
God it was evil.
I would say you should be worried about using primitives over wrappers only when you profile your application and see that the autoboxing is a performance or memory issue. In my experience memory becomes an issue before CPU cycles when talking about primitives vs wrapping objects.