lintcode-solutions
  • LintCode 刷题笔记
  • 课程笔记
    • Backtracking
    • Binary Search
    • Divide & Conquer
    • Breadth First Search
    • Depth First Search
    • Linked List & Array
    • Two Pointers
    • Stack, Queue and Heap
    • Dynamic Programming
    • Two Pointers Advanced
    • Union Find and Trie
    • Dynamic Programming Advanced
  • 基础知识储备
    • Python
      • Stack and Queue
      • Namedtuple
      • Priority Queue
      • isinstance()
      • OrderedDict
      • set and frozen set
      • Counter
      • Heap
    • Bit Manipulation
    • Fenwick Tree or Binary Indexed Tree
    • Rabin-Karp Algorithm
    • Sort
      • Merge Sort
      • Quick Sort
      • Heap Sort
  • LintCode 练习题
    • Binary Search
  • OJ Review
    • Aug 7, 2018
    • Aug 8, 2018
    • Aug 9, 2018
    • Aug 13, 2018
    • Aug 17, 2018
    • Aug 19, 2018
    • Aug 24, 2018
    • Aug 26, 2018
    • Aug 27, 2018
    • Aug 29, 2018
    • Sep 1, 2018
    • Sep 2, 2018
    • Sep 3, 2018
    • Sep 4, 2018
    • Oct 28, 2018
    • Nov 13, 2018
Powered by GitBook
On this page
  • String
  • String.substring()
  • String vs StringBuilder vs StringBuffer
  • Map
  • java.util.HashMap.containsKey()
  • HashMap vs. TreeMap vs. HashTable vs. LinkedHashMap
  • KMP
  1. OJ Review

Aug 7, 2018

String

String.substring()

The java string substring() method returns a part of the string.

We pass begin index and end index number position in the java substring method where start index is inclusive and end index is exclusive. In other words, start index starts from 0 whereas end index starts from 1.

You can get substring from the given string object by one of the two methods:

  1. public String substring(int startIndex): This method returns new String object containing the substring of the given string from specified startIndex (inclusive).

  2. public String substring(int startIndex, int endIndex): This method returns new String object containing the substring of the given string from specified startIndex to endIndex.

In case of string:

  • startIndex: inclusive

  • endIndex: exclusive

Example:

public class TestSubstring{  
    public static void main(String args[]){  
        String s="SachinTendulkar";  
        System.out.println(s.substring(6));      //Tendulkar  
        System.out.println(s.substring(0,6));    //Sachin  
    }  
}  

Output:

Tendulkar
Sachin

String vs StringBuilder vs StringBuffer

Consider below code with three concatenation functions with three different types of parameters, String, StringBuffer and StringBuilder.

// Java program to demonstrate difference between String,
// StringBuilder and StringBuffer
class Geeksforgeeks
{
    // Concatenates to String
    public static void concat1(String s1)
    {
        s1 = s1 + "forgeeks";
    }
 
    // Concatenates to StringBuilder
    public static void concat2(StringBuilder s2)
    {
        s2.append("forgeeks");
    }
 
    // Concatenates to StringBuffer
    public static void concat3(StringBuffer s3)
    {
        s3.append("forgeeks");
    }
 
    public static void main(String[] args)
    {
        String s1 = "Geeks";
        concat1(s1);  // s1 is not changed
        System.out.println("String: " + s1);
 
        StringBuilder s2 = new StringBuilder("Geeks");
        concat2(s2);  // s2 is changed
        System.out.println("StringBuilder: " + s2);
 
        StringBuffer s3 = new StringBuffer("Geeks");
        concat3(s3);  // s3 is changed
        System.out.println("StringBuffer: " + s3);
    }
}

Output:

String: Geeks
StringBuilder: Geeksforgeeks
StringBuffer: Geeksforgeeks

Explanation:

  1. Concat1 : In this method, we pass a string "Geeks" and perform "s1 = s1 + "forgeeks"". The string passed from main() is not changed, this is due to the fact that String is immutable. Altering the value of string creates another object and s1 in concat1() stores reference of new string. References s1 in main() and concat1() refer to different strings.

  2. Concat2 : In this method, we pass a string "Geeks" and perform "s2.append("forgeeks")" which changes the actual value of the string (in main) to "Geeksforgeeks". This is due to the simple fact that StringBuilder is mutable and hence changes its value.

  3. Concat3 : StringBuffer is similar to StringBuilder except one difference that StringBuffer is thread safe, i.e., multiple threads can use it without any issue. The thread safety brings a penalty of performance.

When to use which one :

  • If a string is going to remain constant throughout the program, then use String class object because a String object is immutable.

  • If a string can change (example: lots of logic and operations in the construction of the string) and will only be accessed from a single thread, using a StringBuilder is good enough.

  • If a string can change, and will be accessed from multiple threads, use a StringBuffer because StringBuffer is synchronous so you have thread-safety.

Map

java.util.HashMap.containsKey()

The java.util.HashMap.containsKey() method is used to check whether a particular key is being mapped into the HashMap or not. It takes the key element as a parameter and returns True if that element is mapped in the map.

Syntax:

Hash_Map.containsKey(key_element)

Parameters: The method takes just one parameter key_element that refers to the key whose mapping is supposed to be checked inside a map.

Return Value: The method returns boolean true if the presence of the key is detected else false .

Below programs are used to illustrate the working of java.util.HashMap.containsKey() Method:

Program 1: Mapping String Values to Integer Keys.

// Java code to illustrate the containsKey() method
import java.util.*;
 
public class Hash_Map_Demo {
    public static void main(String[] args)
    {
 
        // Creating an empty HashMap
        HashMap<Integer, String> hash_map = new HashMap<Integer, String>();
 
        // Mapping string values to int keys
        hash_map.put(10, "Geeks");
        hash_map.put(15, "4");
        hash_map.put(20, "Geeks");
        hash_map.put(25, "Welcomes");
        hash_map.put(30, "You");
 
        // Displaying the HashMap
        System.out.println("Initial Mappings are: " + hash_map);
 
        // Checking for the key_element '20'
        System.out.println("Is the key '20' present? " + 
        hash_map.containsKey(20));
 
        // Checking for the key_element '5'
        System.out.println("Is the key '5' present? " + 
        hash_map.containsKey(5));
    }
}

Output:

Initial Mappings are: {20=Geeks, 25=Welcomes, 10=Geeks, 30=You, 15=4}
Is the key '20' present? true
Is the key '5' present? false

Program 2: Mapping Integer Values to String Keys.

// Java code to illustrate the containsKey() method
import java.util.*;
 
public class Hash_Map_Demo {
    public static void main(String[] args)
    {
 
        // Creating an empty HashMap
        HashMap<String, Integer> hash_map = new HashMap<String, Integer>();
 
        // Mapping int values to string keys
        hash_map.put("Geeks", 10);
        hash_map.put("4", 15);
        hash_map.put("Geeks", 20);
        hash_map.put("Welcomes", 25);
        hash_map.put("You", 30);
 
        // Displaying the HashMap
        System.out.println("Initial Mappings are: " + hash_map);
 
        // Checking for the key_element 'Welcomes'
        System.out.println("Is the key 'Welcomes' present? " + 
        hash_map.containsKey("Welcomes"));
 
        // Checking for the key_element 'World'
        System.out.println("Is the key 'World' present? " + 
        hash_map.containsKey("World"));
    }
}

Output:

Initial Mappings are: {4=15, Geeks=20, You=30, Welcomes=25}
Is the key 'Welcomes' present? true
Is the key 'World' present? false

HashMap vs. TreeMap vs. HashTable vs. LinkedHashMap

Map Overview

There are 4 commonly used implementations of Map in Java SE - HashMap, TreeMap, Hashtable and LinkedHashMap. If we use one sentence to describe each implementation, it would be the following:

  • HashMap is implemented as a hash table, and there is no ordering on keys or values.

  • TreeMap is implemented based on red-black tree structure, and it is ordered by the key.

  • LinkedHashMap preserves the insertion order.

  • Hashtable is synchronized, in contrast to HashMap.

This gives us the reason that HashMap should be used if it is thread-safe, since Hashtable has overhead for synchronization.

TreeMap

A TreeMap is sorted by keys. Let's first take a look at the following example to understand the "sorted by keys" idea.

class Dog {
    String color;
    Dog(String c) {
        color = c;
    }
    public boolean equals(Object o) {
        return ((Dog) o).color == this.color;
    }
    public int hashCode() {
        return color.length();
    }
    public String toString(){
        return color + " dog";
    }
}
public class TestTreeMap {
    public static void main(String[] args) {
        Dog d1 = new Dog("red");
        Dog d2 = new Dog("black");
        Dog d3 = new Dog("white");
        Dog d4 = new Dog("white");
        TreeMap treeMap = new TreeMap();
        treeMap.put(d1, 10);
        treeMap.put(d2, 15);
        treeMap.put(d3, 5);
        treeMap.put(d4, 20);
        for (Entry entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }
}

Output:

Exception in thread “main” java.lang.ClassCastException: collection.Dog cannot be cast to java.lang.Comparable
at java.util.TreeMap.put(Unknown Source)
at collection.TestHashMap.main(TestHashMap.java:35)

Since TreeMaps are sorted by keys, the object for key has to be able to compare with each other, that's why it has to implement Comparable interface. For example, you use String as key, because String implements Comparable interface. Let's change the Dog, and make it comparable.

class Dog implements Comparable{
    String color;
    int size;
    Dog(String c, int s) {
        color = c;
        size = s;
    }

    public String toString(){
        return color + " dog";
    }

    @Override
    public int compareTo(Dog o) {
        return  o.size - this.size;
    }
}

public class TestTreeMap {
    public static void main(String[] args) {
        Dog d1 = new Dog("red", 30);
        Dog d2 = new Dog("black", 20);
        Dog d3 = new Dog("white", 10);
        Dog d4 = new Dog("white", 10);
        TreeMap treeMap = new TreeMap();
        treeMap.put(d1, 10);
        treeMap.put(d2, 15);
        treeMap.put(d3, 5);
        treeMap.put(d4, 20);
        for (Entry entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }
}

Output:

red dog – 10
black dog – 15
white dog – 20

It is sorted by key, i.e., dog size in this case. If "Dog d4 = new Dog("white", 10);" is replaced with "Dog d4 = new Dog("white", 40);", the output would be:

white dog – 20
red dog – 10
black dog – 15
white dog – 5

The reason is that TreeMap now uses compareTo() method to compare keys. Different sizes make different dogs!

HashMap

If key of the HashMap is self-defined objects, then equals() and hashCode() contract need to be followed.

class Dog {
    String color;
    Dog(String c) {
      color = c;
    }
    public String toString(){
      return color + " dog";
    }
}
public class TestHashMap {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        Dog d1 = new Dog("red");
        Dog d2 = new Dog("black");
        Dog d3 = new Dog("white");
        Dog d4 = new Dog("white");
        hashMap.put(d1, 10);
        hashMap.put(d2, 15);
        hashMap.put(d3, 5);
        hashMap.put(d4, 20);
        //print size
        System.out.println(hashMap.size());
        //loop HashMap
        for (Entry entry : hashMap.entrySet()) {
            System.out.println(entry.getKey().toString() + " - " + entry.getValue());
        }
    }
}

Output:

white dog – 5
black dog – 15
red dog – 10
white dog – 20

Note here, we add "white dogs" twice by mistake, but the HashMap takes it. This does not make sense, because now we are confused how many white dogs are really there. The Dog class should be defined as follows:

class Dog {
    String color;
    Dog(String c) {
        color = c;
    }

    public boolean equals(Object o) {
        return ((Dog) o).color == this.color;
    }
    public int hashCode() {
        return color.length();
    }
    public String toString(){
        return color + " dog";
    }
}

Now the output is:

red dog – 10
white dog – 20
black dog – 15

The reason is that HashMap doesn't allow two identical elements. By default, the hashCode() and equals() methods implemented in Object class are used. The default hashCode() method gives distinct integers for distinct objects, and the equals() method only returns true when two references refer to the same object. Check out the hashCode() and equals() contract if this is not obvious to you.

LinkedHashMap

LinkedHashMap is a subclass of HashMap. That means it inherits the features of HashMap. In addition, the linked list preserves the insertion-order. Let's replace the HashMap with LinkedHashMap using the same code used for HashMap.

class Dog {
    String color;
    Dog(String c) {
        color = c;
    }

    public boolean equals(Object o) {
        return ((Dog) o).color == this.color;
    }
    public int hashCode() {
        return color.length();
    }
    public String toString(){
        return color + " dog";
    }
}

public class TestHashMap {
    public static void main(String[] args) {
        Dog d1 = new Dog("red");
        Dog d2 = new Dog("black");
        Dog d3 = new Dog("white");
        Dog d4 = new Dog("white");
        LinkedHashMap linkedHashMap = new LinkedHashMap();
        linkedHashMap.put(d1, 10);
        linkedHashMap.put(d2, 15);
        linkedHashMap.put(d3, 5);
        linkedHashMap.put(d4, 20);
        for (Entry entry : linkedHashMap.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }
}

Output is:

red dog – 10
black dog – 15
white dog – 20

The difference is that if we use HashMap the output could be the following - the insertion order is not preserved.

red dog – 10
white dog – 20
black dog – 15

Hashtable

From Java Doc: The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.

KMP

PreviousOJ ReviewNextAug 8, 2018

Last updated 6 years ago