LightBlog

Java - java.lang package Classes

The most commonly used and general purpose classes which are required for any java program are grouped into a package which is nothing but a “java.lang.package”.

All the classes and interfaces which are available in this package are by default available to any java program. There is no need to import this class.


1.      Object Class
2.      String class
3.      StringBuffer Class
4.      StringBuilder Class
5.      Wrapper Classes


1.Object Class
The most common general methods which can be applicable on any java object are defined in object class. Object class is the parent class of any java class, whether it is predefined or programmer defined, hence all the object class methods are by default available to any java class. 

Object class define the following 11 methods

1.toString():Returns a string representation of the object.
·         When ever we are passing object reference as argument to s.o.p() internally JVM will call toString() on that object.

·         If we are not providing toString() then Object class toString() will be executed which is implemented as follows
public String toString() {
          return getClass.getName() + '@' + Integer.toHexString(HashCode);
   }

2.equals(Object otherObject) – As method name suggests, is used to simply verify the equality of two objects. It’s default implementation simply check the object references of two objects to verify their equality. By default, two objects are equal if and only if they are stored in the same memory address.

3.hashcode() – Returns a unique integer value for the object in runtime. By default, integer value is mostly derived from memory address of the object in heap (but it’s not mandatory always).

Relation between equals() & hashcode() methods
·         If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

·         Whenever we override the equals() method, we should override hashcode() method.

·         In String class(not StringBuilder, StringBuffer) & All Wrapper classes equals() method is overridden for Content Comparison

Compare two employee Objects based on Their Id?
public class Employe {
       int id;
       String name;
//Setters & Getters
       @Override
       public boolean equals(Object obj) {       
              Employe e = (Employe) obj;
              boolean flag = false;
              if (this.getId() == e.getId()) {
                     flag = true;
              }
              return flag;
       }
       public static void main(String[] args) {
              Employe e1 = new Employe();
              Employe e2 = new Employe();
              e1.setId(101);
              e2.setId(101);
              System.out.println(e1.equals(e2));//true
       }
}
So are we done? Not yet. Lets test again above modified Employee class in different way.
public static void main(String[] args) {
              Employe e1 = new Employe();
              Employe e2 = new Employe();
              e1.setId(101);
              e2.setId(101);
             
              Set<Employe> set = new HashSet<>();
              set.add(e1);
              set.add(e2);
              System.out.println(set); //[basic.Employe@15db9742, basic.Employe@6d06d69c]    
       }
Above class prints two objects in the second print statement. If both employee objects have been equal, in a Set which stores only unique objects, there must be only one instance inside HashSet.

We are missing the second important method hashCode(). As java docs say, if you override equals()method then you must override hashCode() method
public class Employe {
       int id;
       String name;

       @Override
       public boolean equals(Object obj) {       
              Employe e = (Employe) obj;
              boolean flag = false;
              if (this.getId() == e.getId()) {
                     flag = true;
              }
              return flag;
       }
      
       @Override
       public int hashCode() {            
              return getId();
       }
       public static void main(String[] args) {
              Employe e1 = new Employe();
              Employe e2 = new Employe();
              e1.setId(101);
              e2.setId(101);
             
              Set<Employe> set = new HashSet<>();
              set.add(e1);
              set.add(e2);
              System.out.println(set); //[basic.Employe@65]           
       }
}
Apache commons provide two excellent utility classes EqualsBuilder & HashCodeBuilder  for generating hash code and equals methods.

4.clone(): Creates a new object of the same class as this object which implements Clonable interface.
Test t1 = new Test();
Test t2 = (Test)t1.clone();
An Object is said to be cloneable iff the corresponding class has to implement java.lang.cloneable interface. It doesn’t contain any methods it is a marker interface.

5.finalize():Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

6.getClass():Returns the runtime class of an object.getClass(), or the class-literal - Foo.class return a Class object, which contains some metadata about the class:
·         name
·         package
·         methods
·         fields
·         constructors
·         annotations
we can create Class object by following ways
Class c = Class.forName(“StudentBO”)
Class c = StudentBO.class
Class c = a.getClass();

public static void main(String[] args) throws Exception {
              TestApp a = new TestApp();
              Class c1 = a.getClass();
             
               Class c = Class.forName("java.lang.String");
               System.out.print("Class represented by c : " + c.toString());
               
               Object obj = c.newInstance();
       }

7.wait():Waits to be notified by another thread of a change in this object.

8.wait(long):Waits to be notified by another thread of a change in this object.

9.wait(long, int):Waits to be notified by another thread of a change in this object.

10.notify():Wakes up a single thread that is waiting on this object's monitor.

11.notifyAll():Wakes up all threads that are waiting on this object's monitor.


2.String Class

There are two ways to create String object:
1.By string literal
String s1="Welcome";  
String s2="Welcome";//It doesn't create a new instance  

2.By new keyword
String s1=new String("Welcome");//creates two objects and one reference variable


Understand the following cases

Case 1 : literal VS Object
public class StringDemo {
       public static void main(String[] args) {
              String s1 = "Cat";
              String s2 = "Cat";

              String s3 = new String("Cat");

              System.out.println(s1 == s2); // true
              System.out.println(s1 == s3); // false
       }
}
To be clear what this code is making is on the first line of code it will create the String s1 = "Cat"and store this on the String pool, and on the second line of code it will create the String s2 and reference to "Cat" because this already exist on the String pool. But line 3 will create a new reference of this string no matter if this already exist


Case 2:
       String s1 = "abc";
       String s2 = s1;
              s1 += "d";
       System.out.println(s1+", "+s2+", "+(s1==s2));

abcd, abc, false
Case 3:
StringBuffer s1 = new StringBuffer("abc");
StringBuffer s2 = s1;
     s1.append("d");
System.out.println(s1+", "+s2+", "+(s1==s2));

abcd, abcd, true

StringBuffer operates on Same Object .


Case 4:
              String a = "hello" + " world!";
              String b = "hello world!";
              System.out.println(a==b); //TRUE
When concatenating two string literals "a" + "b" the jvm joins the two values and then check the string pool, then it realizes the value already exists in the pool so it just simply assign this reference to the String.


Case 5 : (+= uses StringBuilder Inside to Create & Append String)
              String a = "Bye";
                     a += " bye!";
                    
              String b = "Bye bye!";
             
              System.out.println(a == b);//FALSE
Your example C is kind of different tho, because you’re using the += operator which when compiled to bytecode it uses StringBuilder to concatenate the strings, so this creates a new instance of StringBuilder Object thus pointing to a different reference. (string pool vs Object)
Oracle Says, To improve performance, instead of using string concatenation, use StringBuffer.append().String objects are immutable


Performance

It’s better to use StringBuilder (it’s an unsynchronized version; when do you build strings in parallel?) these days, in almost every case, but here’s what happens:
When you use + with two strings, it compiles code like this:
String third = first + second;

To something like this
StringBuilder builder = new StringBuilder( first );
builder.append( second );
third = builder.toString();

for example, you might be using many different appending statements, or a loop like this:
for( String str : strings ) {
  out += str;
}

In this case, a new StringBuilder instance, and a new String (the new value of out – Strings are immutable) is required in each iteration. This is very wasteful. Replacing this with a single StringBuilder means you can just produce a single String and not fill up the heap with Strings you don’t care about

To get the String which is created in SCP while executing String(“welcome”), we use intern() method
String s=new String("Welcome");  
String s2=s.intern();  
System.out.println(s2);//Sachin  

In java, string objects are immutable. Immutable simply means unmodifiable or unchangeable.
class Testimmutablestring{  
 public static void main(String args[]){  
   String s1="Sachin";  
   s.concat(" Tendulkar");//concat() method appends the string at the end  
   System.out.println(s);//will print Sachin because strings are immutable objects  
 }  
}  



3,4.StringBuffer, StringBuilder Classes

String
StringBuffer
String class is immutable.
StringBuffer class is mutable.
String is slow and consumes more memory when you concat too many strings because every time it creates new instance.
StringBuffer is fast and consumes less memory when you cancat strings.
String class overrides the equals() method of Object class. So you can compare the contents of two strings by equals() method.
StringBuffer class doesn't override the equals() method of Object class.
StringBuilder is non-synchronized i.e. not thread safe. It means two threads can call the methods of StringBuilder simultaneously.
StringBuffer is synchronized i.e. thread safe. It means two threads can't call the methods of StringBuffer simultaneously.

Creates an empty StringBuffer object with default initial capacity 16.If it reaches max capacity then a new StringBuffer object will be created with new capacity = (currentcapacity + 1) * 2
StringBuffer sb = new StringBuffer();


StringBuffer
StringBuilder
StringBuffer is synchronized i.e. thread safe. It means two threads can't call the methods of StringBuffer simultaneously.
StringBuilder is non-synchronized i.e. not thread safe. It means two threads can call the methods of StringBuilder simultaneously.
StringBuffer is less efficient than StringBuilder.
StringBuilder is more efficient than StringBuffer.



String                   
StringBuffer        
StringBuilder
Storage Area
Modifiable 
Thread Safe
Performance
Constant String Pool
No (immutable)     
      Yes          
      Fast         
      Heap       
 Yes( mutable )  
        Yes      
   Very slow     
     Heap
 Yes( mutable )
     No
    Fast


Examples on String, StringBuffer, StringBuilder

1.What is immutable object? Can you write immutable object?
Don’t confuse over SingleTon class
Immutable classes are Java classes whose objects can not be modified once created. 
1.       Declare the class as final so it can’t be extended.
2.       Make all fields private & final so that direct access is not allowed & it’s values can be assigned only once..
3.       Initialize all the fields via a constructor
4.       Write getters only, not setters.
// An immutable class
public final class Student {
       final String name;
       final int regNo;

       public Student(String name, int regNo) {
              this.name = name;
              this.regNo = regNo;
       }
       public String getName() {
              return name;
       }
       public int getRegNo() {
              return regNo;
       }
}

// Driver class
class Test {
       public static void main(String args[]) {
              Student s = new Student("ABC", 101);
              System.out.println(s.name);
              System.out.println(s.regNo);

              // Uncommenting below line causes error
              // s.regNo = 102;
       }
}


2.What is Singleton? Can you write critical section code for singleton?
A Singleton class is one which allows us to create only one object for JVM.
Rules:
·         Create Singleton class Object make it as PRIVATE
·         Create PRIVATE contrcutor
·         Every Singleton class contains at least one factory method
class Student {
       private static Student st;

       private Student() {
              System.out.println("OBJECET Created FIRST TIME");
       }

       public static Student getObject() {
              if (st == null) {
                     st = new Student();
              } else {
                     System.out.println("OBJECET ALREDAY CREATED");
              }
              return st;
       }
}

public class Singleton {
       public static void main(String[] args) {
              Student s1 = Student.getObject();
              Student s2 = Student.getObject();
              System.out.println(s1.hashCode());
              System.out.println(s2.hashCode());
       }
}
In above code, it will create multiple instances of Singleton class if called by more than one thread parallel

Double checked locking of Singleton is a way to ensure only one instance of Singleton class is created through application life cycle.

This will bring us to double checked locking pattern, where only critical section of code is locked. Programmer call it double checked locking because there are two checks for _instance == null, one without locking and other with locking (inside synchronized) block. Here is how double checked locking looks like in Java
public static Singleton getInstanceDC() {
        if (_instance == null) {                // Single Checked
            synchronized (Singleton.class) {
                if (_instance == null) {        // Double checked
                    _instance = new Singleton();
                }
            }
        }
        return _instance;
}


How do you reverse a String in Java without using StringBuffer?
The Java library provides String Buffer and StringBuilder class with reverse() method, which can be used to reverse String in Java.
String reverse = "";
String source= "My Name is Khan";
        for(int i = source.length() -1; i>=0; i--){
            reverse = reverse + source.charAt(i);
        }


How to Print duplicate characters from String?
public class RepreatedChar {
       public static void main(String[] args) {
              String a = "success";

              // 1.convert into char array
              char[] c = a.toCharArray();

              // 2.create Hashmap store key as character, count as value
              HashMap map = new HashMap<>();
              for (char ch : c) {

                     // 3.Check if Map contains given Char as <key> or not
                     if (map.containsKey(ch)) {
                           // if their, get the value & increment it
                           int i = (int) map.get(ch);
                           i++;
                           // add updated value to it
                           map.put(ch, i);
                     } else {
                           // if not their , add key & value as 1
                           map.put(ch, 1);
                     }
              }
                    
               Set  set =  map.entrySet();
               Iterator iterator = set.iterator() ;
               while (iterator.hasNext()) {
                     Map.Entry entry = (Entry) iterator.next();
                     System.out.println(entry.getKey()+" : "+entry.getValue());
                    
              }
       }
}
s : 3
c : 2
u : 1
e : 1


Reverse String in Java
1.       Get String length
2.       Iterate by using charAt() in reverse & append to new String
public class ReverseString {
public static void main(String[] args) {
      
       String s = "satyam";
       String rev="";
       int len = s.length();
      
       for(int i=(len-1);i>=0;i--){
             
              rev = rev+s.charAt(i);
       }
      
       System.out.println(rev);
}
}


Is String contains Number or not?
public class RegEx {
       public static void main(String[] args) {
              // Regular expression in Java to check if String is number or not
              Pattern pattern = Pattern.compile(".*[^0-9].*");         
              String[] inputs = { "123", "-123", "123.12", "abcd123" };
              /* Matches m = pattern.match(input);
               * boolean ch = m.match();   */          

              for (String input : inputs) {
System.out.println("does " + input + " is number : " + !pattern.matcher(input).matches());
              }

       // Regular expression in java to check if String is 6 digit number or  not
              String[] numbers = { "123", "1234", "123.12", "abcd123", "123456" };
              Pattern digitPattern = Pattern.compile("\\d{6}");
              // Pattern digitPattern = Pattern.compile("\\d\\d\\d\\d\\d\\d");

              for (String number : numbers) {
                     System.out.println("does " + number + " is 6 digit number : " + digitPattern.matcher(number).matches());
              }
       }
}


Reverse Words in a String
public class RevWords {
       public static void main(String[] args) {
              // using s.split("\\s");
              String s = "My name is Satya";
              String words[] = s.split("\\s");
              String rev = "";
              int len = words.length;
              for (int i = (len - 1); i >= 0; i--) {
                     rev = rev + words[i];
              }
              System.out.println(rev);

              // using Collections.reverse(str)
              List<String> word = Arrays.asList(s.split("\\s"));
              Collections.reverse(word);
              System.out.println(word);
       }
}


5.Wrapper classes
Collections in Java deal only with objects; to store a primitive type in one of these classes, you need to wrap the primitive type in a class.

The main objectives of wrapper classes are:
·         To Wrap primitives into object form. So that we can handle primitives also just like objects.
·         To Define several utility functions for the primitives(converting primitive to the string form etc)

Each primitive type has a corresponding wrapper class.
Primitive Type
Wrapper Class
double
Double
float
Float
long
Long
int
Integer
short
Short
byte
Byte
char
Character
boolean
Boolean


Primitive type to wrapper class
1.using constrcutors
// 1. using constructor
Integer object = new Integer(10);

2.using static factory methods such as valueOf() (except Character)
// 2. using static factory method
Integer anotherObject = Integer.valueOf(10);
 Similarly, we can convert other primitive types like boolean to Boolean, char to Character, etc.


Wrapper class to primitive type
Converting from wrapper to primitive type is simple. We can use the corresponding methods to get the primitive type. e.g. intValue()doubleValue()shortValue() etc.
Integer object = new Integer(10);

int val = object.intValue();    //wrapper to primitive



Autoboxing and Unboxing

Beginning with JDK 5, Java added two important features: autoboxing and auto-unboxing.

Autoboxing:
 is the automatic conversion of the primitive types into their corresponding object wrapper classes. 
For example, converting an int to an Integer, a char to a Character, and so on.
We can simply pass or assign a primitive type to an argument or reference accepting wrapper class object. e.g.
List<Integer> integerList = new ArrayList<>();

for (int i = 1; i < 50; i += 2)
{
    integerList.add(Integer.valueOf(i));        //autoboxing
}


Unboxing:
  happens when the conversion happens from wrapper class to its corresponding primitive type. It means we can pass or assign a wrapper object to an argument or reference accepting primitive type. e.g.
public static int sumOfEven(List<Integer> integerList)
{
    int sum = 0;
    for (Integer i: integerList) {
        if (i % 2 == 0)
            sum += i;           //Integer to int
    }
    return sum;
}
In above example, the remainder (%) and unary plus (+=) operators does not apply on Integer objects. The compiler automatically converts an Integer to an int at runtime by invoking the intValue()method.


Wrapper Classes Internal Caching

Wrapper classes are immutable in java, Right? “YES”. So, like string pool, they can also have their pool, right? “Great Idea”. Well, it’s already there. JDK provided wrapper classes also provide this in form of instance pooling i.e. each wrapper class store a list of commonly used instances of own type in form of cache and whenever required, you can use them in your code. It helps in saving lots of byes in your program runtime.

In Integer.java class there is an inner class i.e. IntegerCache. When you assign a new int to Integer type like below
Integer i = 10; //OR
Integer i = Integer.valueOf(10);

An already created Integer instance is returned and reference is stored in i. Please note that if you use new Integer(10); then a new instance of Integer class will be created and caching will not come into picture. 
Its only available when you use Integer.valueOf() OR directly primitive assignment (which ultimately uses valueOf() function)
public class IntegerCacheDemo {

    public static void main(String[] args) {

        Integer a1 = 100;
        Integer a2 = 100;
        Integer a3 = new Integer(100);

        System.out.println(a1 == a2);
        System.out.println(a1 == a3);
    }
}

Output:
true
false

If you want to store a bigger number of instances, you can use runtime parameter as below:
-Djava.lang.Integer.IntegerCache.high=2000

Share on Google Plus

About Unknown

This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.

0 comments:

Post a Comment