Professional Documents
Culture Documents
A Strategy For Defining Immutable Objects: Hashcode Map Keys and Set Elements
A Strategy For Defining Immutable Objects: Hashcode Map Keys and Set Elements
A Strategy For Defining Immutable Objects: Hashcode Map Keys and Set Elements
The following rules define a simple strategy for creating immutable objects. Not all classes documented
as "immutable" follow these rules. This does not necessarily mean the creators of these classes were
sloppy they may have good reason for believing that instances of their classes never change after
construction. However, such strategies require sophisticated analysis and are not for beginners.
1. Don't provide "setter" methods methods that modify fields or objects referred to by fields.
2. Make all fields final and private.
3. Don't allow subclasses to override methods. The simplest way to do this is to declare the
class asfinal. A more sophisticated approach is to make the constructor private and construct
instances in factory methods.
4. If the instance fields include references to mutable objects, don't allow those objects to be
changed:
o
Don't share references to the mutable objects. Never store references to external,
mutable objects passed to the constructor; if necessary, create copies, and store
references to the copies. Similarly, create copies of your internal mutable objects
when necessary to avoid returning the originals in your methods.
1.
2.
3.
4.
5.
6.
7.
THREADS:
class A1 implements Runnable {
private int counter = 0;
@Override
public void run() {
counter++;
System.out.println("Running A1 -> " + counter);
}
}
class B1 extends Thread {
private int counter = 0;
@Override
2.
public void demoMethod(){
synchronized (DemoClass.class) //this object lock
{
//other thread safe code
}
}
3.
private final static Object lock = new Object(); // w/o static object lock.
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
new
HashMap<Integer,
Integer>();
entry
:
map.entrySet())
{
entry.getKey() +
", Value
= "
+
Integer>
map
over
(Integer
key
System.out.println("Key
new
HashMap<Integer,
Integer>();
keys
map.keySet())
"
+
only
{
key);
values
map.values())
"
+
only
{
value);
}
//iterating
for
over
(Integer
value
System.out.println("Value
entry.getValue());
}
STRING SAFETY:
1) We know in java load classes using Class.forName(string). If Strings were mutable, then someone wrote the
code to load java.io.Writer. This string variable will be in pool. Now, some evil code can access this pool and
change the string to com.MakeHavocWriter and now when code gets executed, one can easily imagine the
consequences.
2) String pool is there so that one String instance can be referred from multiple reference variables. If string is
mutable, then one object can change the string content and other will see this undesired value.
3. Thread safe as immutable.
Class.forName() loads the class in memory. To create an instance of this class, we need to use newInstance().
Using class loaders loadClass()
Just like above mechanism, class loaders loadClass() method does the same thing.
instance.getClass().getClassLoader().loadClass("NewClass").newInstance();
Using Reflection
This is also a popular way to create new instances in most of available frameworks.
constructor.newInstance(); or
class.newInstance();
Static Methods
If a subclass defines a static method with the same signature as a static method in the superclass,
then the method in the subclass hides the one in the superclass.
The distinction between hiding a static method and overriding an instance method has important
implications:
The version of the overridden instance method that gets invoked is the one in the
subclass.
The version of the hidden static method that gets invoked depends on whether it is
invoked from the superclass or the subclass.
Consider an example that contains two classes. The first is Animal, which contains one instance
method and one static method:
public class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
public void testInstanceMethod() {
System.out.println("The instance method in Animal");
}
}
The Cat class overrides the instance method in Animal and hides the static method in Animal.
The main method in this class creates an instance of Cat and invokes testClassMethod() on the
class andtestInstanceMethod() on the instance.
The output from this program is as follows:
The static method in Animal
The instance method in Cat
As promised, the version of the hidden static method that gets invoked is the one in the
superclass, and the version of the overridden instance method that gets invoked is the one in the
subclass.
Interface Methods
Default methods and abstract methods in interfaces are inherited like instance methods.
However, when the supertypes of a class or interface provide multiple default methods with the
same signature, the Java compiler follows inheritance rules to resolve the name conflict. These
rules are driven by the following two principles:
Instance methods are preferred over interface default methods.
Consider the following classes and interfaces:
public class Horse {
public String identifyMyself() {
return "I am a horse.";
}
}
public interface Flyer {
default public String identifyMyself() {
return "I am able to fly.";
}
}
public interface Mythical {
default public String identifyMyself() {
return "I am a mythical creature.";
}
}
public class Pegasus extends Horse implements Flyer, Mythical {
public static void main(String... args) {
Pegasus myApp = new Pegasus();
System.out.println(myApp.identifyMyself());
}
}
am a horse.
Methods that are already overridden by other candidates are ignored. This circumstance
can arise when supertypes share a common ancestor.
Consider the following interfaces and classes:
public interface Animal {
default public String identifyMyself() {
return "I am an animal.";
}
}
public interface EggLayer extends Animal {
default public String identifyMyself() {
return "I am able to lay eggs.";
}
}
public interface FireBreather extends Animal { }
public class Dragon implements EggLayer, FireBreather {
public static void main (String... args) {
Dragon myApp = new Dragon();
System.out.println(myApp.identifyMyself());
}
}
I am just having hard time to understand concept behind putting wait() in object class For this questions sake
consider as if wait() and notifyAll() are in thread class
In the Java language, you wait() on a particular instance of an Object -- a monitor assigned to that object to be
precise. If you want to send a signal to a single thread that is waiting on that specific object instance then you
call notify() on that object. If you want to send a signal to all threads that are waiting on that object instance, you
use notifyAll() on that object.
If wait() and notify() were on the Thread instead then each thread would have to know the status of every other
thread. How would thread1 know that thread2 was waiting for access to a particular resource? If thread1 needed
to call thread2.notify() it would have to somehow find out that thread2 was waiting. There would need to be some
mechanism for threads to register the resources or actions that they need so others could signal them when stuff
was ready or available.
In Java, the object itself is the entity that is shared between threads which allows them to communicate with each
other. The threads have no specific knowledge of each other and they can run asynchronously. They run and they
lock, wait, and notify on the object that they want to get access to. They have no knowledge of other threads and
don't need to know their status. They don't need to know that it is thread2 which is waiting for the resource -they just notify on the resource and whomever it is that is waiting (if anyone) will be notified.
1. yield() 2. join() 3.sleep()
1.
yield() method pauses the currently executing thread temporarily for giving a chance to the remaining
waiting threads of the same priority to execute. If there is no waiting thread or all the waiting threads
have a lower priority then the same thread will continue its execution. The yielded thread when it will get
the chance for execution is decided by the thread scheduler whose behavior is vendor dependent.
2.
join() If any executing thread t1 calls join() on t2 i.e; t2.join() immediately t1 will enter into waiting state
until t2 completes its execution.
3.
sleep() Based on our requirement we can make a thread to be in sleeping state for a specified period of
time (hope not much explanation required for our favorite method). LOCK NOT RELEASED.
Write a program to swap two numbers with out using third variable?
Connection leak basically happens when we open a connection to the database from our application and forget to
close it, or for some reasons it doesnt get closed.
To implement connection pooling we basically use these connection string properties ;
1) Connection Lifetime (Default 0) - When a connection is returned to the pool, its creation time is compared
with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified
by Connection Lifetime. This is useful in clustered configurations to force load balancing between a running server
and a server just brought online. A value of zero (0) will cause pooled connections to have the maximum time-out.
2) Pooling (Default true) -; When true, the connection is drawn from the appropriate pool, or if necessary,
created and added to the appropriate pool.
3) Max Pool Size (Default 100 ) -:The maximum number of connections allowed in the pool.
4) Min Pool Size (Default 0 ) -:The minimum number of connections allowed in the pool.
5) Connect Timeout or Connection Timeout (Default 15) -: The length of time (in seconds) to wait for a
connection to the server before terminating the attempt and generating an error.
Difference between save and persist method in Hibernate
First difference between save and persist is there return type. Similar to save method persist also INSERT records
into database but return type of persist is void while return type of save is Serializable object.
2) Another difference between persist and save is that both methods make a transient instance persistent.
However,persist() method doesn't guarantee that the identifier value will be assigned to the persistent instance
immediately, the assignment might happen at flush time.
3) persist() method guarantees that it will not execute an INSERT statement if it is called outside of transaction
boundaries. save() method does not guarantee the same, it returns an identifier, and if an INSERT has to be
executed to get the identifier (e.g. "identity" generator), this INSERT happens immediately, no matter if you are
inside or outside of a transaction.
4) Because of its above behavior of persist method outside transaction boundary, its useful in long-running
conversations with an extended Session context. On the other hand save method is not good in a long-running
conversation with an extended Session context.
Difference between get and load method
1. Behavior when Object is not found in Session CacheApart from performance this is another difference
between get and load which is worth remembering. get method of Hibernate Session class returns null if object is
not found in cache as well as on database while load() method throwsObjectNotFoundException if object is not
found on cache as well as on database but never return null.
2. Database hitGet method always hit database while load() method may not always hit the database, depending
upon which method is called. other than getId() is called on persistent or entity object.
3. Proxy Get method never returns a proxy, it either returns null or fully initialized Object, while load() method
may return proxy, which is the object with ID but without initializing other properties, which is lazily initialized. If
you are just using returned object for creating relationship and only need Id then load() is the way to go.
4. PerformanceBy far most important difference between get and load in my opinion. get method will return a
completely initialized object if Object is not on the cache but exists on Database, which may involve multiple
round-trips to database based upon object relational mappings while load() method of Hibernate can return
a proxy which can be initialized on demand (lazy initialization) when a non identifier method is accessed. Due to
above reason use of load method will result in slightly better performance, but there is a caveat that proxy
object will throw ObjectNotFoundException later if corresponding row doesnt exists in database, instead of failing
immediately so not a fail fast behavior.5. load method exists prior to get method which is added on user request.
When to use Session get() and load() in Hibernate
1. Use get method to determine if an instance exists or not because it can return null if instance doesnt exists in
cache and database and use load method to retrieve instance only if you think that instance should exists and non
availability is an error condition.
2. As stated in difference number 2 between get and load in Hibernate. get() method could suffer performance
penalty if only identifier method like getId() is accessed. So consider using load method if your code doesn't
access any method other than identifier or you are OK with lazy initialization of object, if persistent object is not in
Session Cache because load() can return proxy.
How to call get records in Hibernate using get and load method
If you look at below code , there is not much difference on calling get() and load() method, though both
are overloadednow and can accept few more parameters but the primary methods looks exactly identical. Its
there behavior which makes them different.
//Example of calling get method of Hiberante Session class
Session session = SessionFactory.getCurrentSession();
Employee Employee = (Employee) session.get(Employee.class, EmployeeID);
//Example of calling load method of Hiberante Session
Over Ridding
Random
Key-
Duplicate
Null
Thread
Collection
Ordering
Access
Value
Elements
Element
Safety
ArrayList
Yes
Yes
No
Yes
Yes
No
LinkedList
Yes
No
No
Yes
Yes
No
HashSet
No
No
No
No
Yes
No
TreeSet
Yes
No
No
No
No
No
HashMap
No
Yes
Yes
No
Yes
No
TreeMap
Yes
Yes
Yes
No
No
No
Vector
Yes
Yes
No
Yes
Yes
Yes
Hashtable
No
Yes
Yes
No
No
Yes
Properties
No
Yes
Yes
No
No
Yes
Stack
Yes
No
No
Yes
Yes
Yes
CopyOnWriteArrayList
Yes
Yes
No
Yes
Yes
Yes
ConcurrentHashMap
No
Yes
Yes
No
No
Yes
CopyOnWriteArraySet
No
No
No
No
Yes
Yes
"What happens On HashMap in Java if the size of the HashMap exceeds a given threshold defined by
load factor ?". Until you know how HashMap works exactly you won't be able to answer this question. If the size
of the Map exceeds a given threshold defined by load-factor e.g. if load factor is .75 it will act to re-size the map
once it filled 75%. Similar to other collection classes like ArrayList, Java HashMap re-size itself by creating a new
bucket array of size twice of previous size of HashMap , and then start putting every old element into that new
bucket array. This process is called rehashingbecause it also applies hash function to find new bucket location.
2.