Interface Segregation Principle

Clients should not be forced to depend upon interfaces that they do not use.

  • Make fine grained interfaces that are client specific
  • Many client specific interfaces are better than one “general purpose” interface
  • Keep your components focused and minimize dependencies between them
  • Notice relationship to the Single Responsibility Principle?
  • avoid ‘god’ interfaces

Liskov Subsitution Principle

If it looks like a duck and quacks like a duck but it needs batteries, you probably have the wrong abstraction.

  • By Barbara Liskov, in 1998
  • Objects in a program would be replaceable with instances of their subtypes WITHOUT altering the correctness of the program.
  • Violations will often fail the “Is a” test.
  • A Square “Is a” Rectangle
  • However, a Rectangle “Is Not” a Square

Open/Closed Principle

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

  • Your classes should be open for extension
  • But closed for modification
  • You should be able to extend a classes behavior, without modifying it.
  • Use private variables with getters and setters – ONLY when you need them.
  • Use abstract base classes

Difference between HashMap and HashSet in Java

HashSet

  1. HashSet class implements the Set interface
  2. In HashSet, we store objects(elements or values) e.g. If we have a HashSet of string elements then it could depict a set of HashSet elements: {“Hello”, “Hi”, “Bye”, “Run”}
  3. HashSet does not allow duplicate elements that mean you can not store duplicate values in HashSet.
  4. HashSet permits to have a single null value.
  5. HashSet is not synchronized which means they are not suitable for thread-safe operations until unless synchronized explicitly.[similarity]

HashSet example:

import java.util.HashSet;
class HashSetDemo{ 
  public static void main(String[] args) {
     // Create a HashSet
     HashSet<String> hset = new HashSet<String>();
 
     //add elements to HashSet
     hset.add("AA");
     hset.add("BB");
     hset.add("CC");
     hset.add("DD");
 
     // Displaying HashSet elements
     System.out.println("HashSet contains: ");
     for(String temp : hset){
        System.out.println(temp);
     }
  }
}

HashSet contains: 
AA
BB
CC
DD

 

HashMap

  1. HashMap class implements the Map interface
  2. HashMap is used for storing key & value pairs. In short, it maintains the mapping of key & value (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This is how you could represent HashMap elements if it has integer key and value of String type: e.g. {1->”Hello”, 2->”Hi”, 3->”Bye”, 4->”Run”}
  3. HashMap does not allow duplicate keys however it allows having duplicate values.
  4. HashMap permits single null key and any number of null values.
  5. HashMap is not synchronized which means they are not suitable for thread-safe operations until unless synchronized explicitly.[similarity]

HashMap example:

import java.util.HashMap;
class HashMapDemo{ 
  public static void main(String[] args) {
     // Create a HashMap
     HashMap<Integer, String> hmap = new HashMap<Integer, String>();
 
     //add elements to HashMap
     hmap.put(1, "AA");
     hmap.put(2, "BB");
     hmap.put(3, "CC");
     hmap.put(4, "DD");
 
     // Displaying HashMap elements
     System.out.println("HashMap contains: "+hmap);
  }
}

HashMap contains: {1=AA, 2=BB, 3=CC, 4=DD}

 

Difference between HashSet and HashMap in Java

HashMap Hash Set
HashMap  is an implementation of Map interface HashSet is an implementation of Set Interface
HashMap Stores data in form of  key-value pair HashSet Store only objects
Put method is used to add element in map Add method is used to add element is Set
In hash map hashcode value is calculated using key object Here member object is used for calculating hashcode value which can be same for two objects so equal () method is used to check for equality if it returns false that means two objects are different.
HashMap is faster than HashSet because unique key is used to access object HashSet is slower than Hashmap

 

NoClassDefFoundError vs ClassNotFoundException

ClassNotFoundException and NoClassDefFoundError occur when a particular class is not found at runtime. However, they occur at different scenarios.

NoClassDefFoundError:

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.

The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.

ClassNotFoundException:

Thrown when an application tries to load in a class through its string name using:

  • The forName method in class Class.
  • The findSystemClass method in class ClassLoader.
  • The loadClass method in class ClassLoader.

but no definition for the class with the specified name could be found. For example, you may have come across this exception when you try to connect to MySQL or Oracle databases and you have not updated the classpath with required JAR files. Most of the time, this exception occurs when you try to run an application without updating the classpath with required JAR files.

ClassNotFoundException NoClassDefFoundError
It is an exception. It is of type java.lang.Exception. It is an error. It is of type java.lang.Error.
It occurs when an application tries to load a class at run time which is not updated in the classpath. It occurs when java runtime system doesn’t find a class definition, which is present at compile time, but missing at run time.
It is thrown by the application itself. It is thrown by the methods like Class.forName(), loadClass() and findSystemClass(). It is thrown by the Java Runtime System.
It occurs when classpath is not updated with required JAR files. It occurs when required class definition is missing at runtime.

 

 

JUnit – assertThat (Hamcrest) – part 3

Ok, it’s time to continue our series of examples Hamcrest matchers usage. Previous blog posts can be found here (part 1part 2).

  • endsWith()

Creates a matcher that matches if the examined String ends with the specified String.

   @Test
    public void endsWithExample() {

        assertThat("Let's test endsWith matcher", endsWith("matcher"));
    }

 

  • equalTo()

Creates a matcher that matches when the examined object is logically equal to the examined object.

   @Test
    public void equalToValueExample() {

        String testValue = "text";

        assertThat(testValue, equalTo("text"));
    }

 

equalTo() can also be used on Arrays in which case it will check the length of the Array and ensure that all the values in the input test array are logically equal to the values of the specified array.

   @Test
    public void equalToArrayExample() {

        assertThat(new String[] {"Jon", "Paul"}, equalTo(new String[] {"Jon", "Paul"}));
    }

 

  • equalToIgnoringCase()

Creates a matcher of String that matches when the examined string is equal to the specified expectedString, ignoring case.

   @Test
    public void equalToIgnoringCaseExample() {

        String testValue = "TeXt";

        assertThat("text", equalToIgnoringCase(testValue));
    }

 

  • equalToIgnoringWhiteSpace()

Creates a matcher of String that matches when the examined string is equal to the specified expected String when whitespace differences are (mostly) ignored. To be exact, the following whitespace rules are applied:

  1. all leading and trailing whitespace of both the expected String and the examined string are ignored
  2. any remaining whitespace, appearing within either string, is collapsed to a single space before comparison
   @Test
    public void equalToIgnoringWhiteSpaceExample() {

        String testValue = "all leading    and trailing whitespace of both    the       expectedString and     the examined string   are       ignored    ";

        // Then
        assertThat(testValue, equalToIgnoringWhiteSpace("all leading and trailing whitespace of both the expectedString and the examined string are ignored"));
    }

 

  • greaterThan()

Creates a matcher of Comparable object that matches when the examined object is greater than the specified value, as reported by the compareTo method of the examined object.

   @Test
    public void greaterThanExample() {

        Integer testValue = 5;

        assertThat(6, is(greaterThan(testValue)));
    }

 

  • greaterThanOrEqualTo()

Creates a matcher of Comparable object that matches when the examined object is greater than or equal to the specified value, as reported by the compareTo method of the examined object.

    @Test
    public void greaterThanOrEqualToExample() {

        Double testValue = 5.5;

        assertThat(5.5, is(greaterThanOrEqualTo(testValue)));
    }

 

  • hasEntry()

Creates a matcher for Maps matching when the examined Map contains at least one entry whose key equals the specified key and whose value equals the specified value.

  @Test
    public void hasEntryExample() {

        Map<Integer, String> myMap = new HashMap<>();
        myMap.put(1, "value");

        assertThat(myMap, hasEntry(1, "value"));
    }

 

  • hasKey()

Creates a matcher for Maps matching when the examined Map contains at least one key that satisfies the specified matcher.

  @Test
    public void hasKeyExample() {

        Map<Integer, String> myMap = new HashMap<>();
        myMap.put(1, "value");
        myMap.put(2, "anotherValue");

        assertThat(myMap, hasKey(1));

 

  • hasValue()

Creates a matcher for Maps matching when the examined Map contains at least one value that is equal to the specified value.

   @Test
    public void hasValueExample() {

        Map<Integer, String> myMap = new HashMap<>();
        myMap.put(1, "value");
        myMap.put(2, "anotherValue");

        assertThat(myMap, hasValue("anotherValue"));
    }

 

  • hasItem()

Creates a matcher for Iterables that only matches when a single pass over the examined Iterable yields at least one item that is equal to the specified item. Whilst matching, the traversal of the examined Iterable will stop as soon as a matching item is found.

   @Test
    public void hasItemExample() {

        List<Integer> testList = Arrays.asList(50, 60, 4, 67, 9);

        assertThat(testList, hasItem(67));

    }

 

  • hasItems()

Creates a matcher for Iterables that matches when consecutive passes over the examined Iterable yield at least one item that is equal to the corresponding item from the specified items. Whilst matching, each traversal of the examined Iterable will stop as soon as a matching item is found.

    @Test
    public void hasItemsExample() {

        List<Integer> testList = Arrays.asList(50, 60, 4, 67, 9);

        assertThat(testList, hasItems(67, 60));
    }

 

  • hasSize()

Creates a matcher for Collections that matches when the size() method returns a value equal to the specified size.

   @Test
    public void hasSizeExample() {

        List<Integer> testList = Arrays.asList(50, 60, 4, 67, 9);

        assertThat(testList, hasSize(5));
    }

 

  • instanceOf()

Creates a matcher that matches when the examined object is an instance of the specified type.

   @Test
    public void instanceOfExample() {

        Object integer = 5;

        assertThat(integer, instanceOf(Integer.class));
    }

 

 

JUnit – assertThat (Hamcrest) – part 2

Let’s continue (you can find Hamcrest matchers – part 1 here) our series of examples how to write JUnit test with Hamcrest matchers usage.

  • comparesEqualTo()

Creates a matcher of a Comparable object that matches when the examined object is equal to the specified value, as reported by the compareTo method of the examined object. The value which, when passed to the compareTo method of the examined object, should return zero.

   @Test
    public void comparesEqualToExample() {

        assertThat(5, comparesEqualTo(5));
    }

 

  • contains()

Various matchers which can be used to check if an input Iterable contains values. The order of the values is important and the number of items in the Iterable must match the number of values being tested.

Test if the input list contains all of the values, the order of items is important.

  @Test
    public void containsItemsExample() {
        // Given
        List<String> names = Arrays.asList("Jon", "Peter", "Paul");

        // Then
        assertThat(names, contains("Jon", "Peter", "Paul"));
    }

Test if the input list contains items which match all of the matchers in the input matchers list, the order of items is important.

   @Test
    public void containsAllMatchersExample() {
        // Given
        List<String> strings = Arrays.asList("Jon", "Peter", "Paul");

        // Then
        List<org.hamcrest.Matcher<? super String>> matchers = new ArrayList<>();
        matchers.add(startsWith("Jo"));
        matchers.add(endsWith("ter"));
        matchers.add(equalTo("Paul"));
        assertThat(strings, contains(matchers));
    }

 

  • containsInAnyOrder()

This one is like contains() but as the name suggest the order of items is not important.

   @Test
    public void containsItemsInAnyOrderExample() {
        // Given
        List<String> names = Arrays.asList("Jon", "Peter", "Paul");

        // Then
        assertThat(names, containsInAnyOrder("Peter", "Jon", "Paul"));
    }

   @Test
    public void containsAllMatchersInAnyOrderExample() {
        // Given
        List<String> strings = Arrays.asList("Jon", "Peter", "Paul");

        // Then
        List<org.hamcrest.Matcher<? super String>> matchers = new ArrayList<>();
        matchers.add(endsWith("ter"));
        matchers.add(startsWith("Jo"));
        matchers.add(equalTo("Paul"));
        assertThat(strings, containsInAnyOrder(matchers));
    }

 

  • containsString()

A matcher that matches if the examined String contains the specified String anywhere.

   @Test
    public void containsStringExample() {
        // Given
        String testValue = "A very short sentence.";

        // Then
        assertThat(testValue, containsString("nt"));
    }

 

  • empty()

A matcher for Collections matching examined collections whose isEmpty method returns true.

    @Test
    public void emptyMatcherExample() {
        // Given
        Queue<String> collectionToTest = new LinkedList<>();

        // Then
        assertThat(collectionToTest, is(empty()));
    }

 

  • emptyArray()

A matcher for arrays that matches when the length of the array is zero.

   @Test
    public void emptyArrayMatcherExample() {
        // Given
        Integer[] arrayToTest = new Integer[0];

        // Then
        assertThat(arrayToTest, is(emptyArray()));
    }

 

  • emptyCollectionOf()

A matcher for Collections matching examined collections whose isEmpty method returns true.

   @Test
    public void emptyCollectionOfMatcherExample() {
        // Given
        Set<String> collectionToTest = new HashSet<>();

        // Then
        assertThat(collectionToTest, is(emptyCollectionOf(String.class)));
    }

 

  • emptyIterable()

A matcher for Iterables matching examined iterable that yield no items.

  @Test
    public void emptyIterableMatcherExample() throws Exception {
        // Given
        ArrayList<String> collectionToTest = new ArrayList<>();

        // Then
        assertThat(collectionToTest, is(emptyIterable()));
    }

 

  • emptyIterableOf()

A matcher for Iterables matching examined iterable that yield no items and is of the given type.

   @Test
    public void emptyIterableOfMatcherExample() throws Exception {
        // Given
        ArrayList<String> collectionToTest = new ArrayList<>();

        // Then
        assertThat(collectionToTest, is(emptyIterableOf(String.class)));
    }

 

 

JUnit – assertThat (Hamcrest) – part 1

Hamcrest is a framework for creating matcher objects. These matcher objects are predicates and are used to write rules which can be satisfied under certain conditions. They are most often used in testing. Hamcrest lets us step beyond simple JUnit asserts and enables us to craft very specific and readable verification code. Hamcrest has the target to make tests as readable as possible. In general, the Hamcrest error messages are also much easier to read. Using Hamcrest matchers also provides more type safety as these matchers uses generics.

Simple Matchers

  • any()
@Test
public void anyMatcherExample() {

    int age = 30;
    assertThat(age, is(any(Integer.class)));        
}
  • anything()
@Test
public void anythingMatcherExample() {

    Integer age = 30;
    assertThat(age, is(anything()));
}
  • arrayContaining()

Does the array contain all given items in the order in which they are input to the matcher?

@Test
public void arrayContainingMatcherExample() {

    String[] names = {"Jon", "Peter", "Paul"};
    assertThat(names, is(arrayContaining("Jon", "Peter", "Paul")));
}
  • arrayContainingInAnyOrder()

Does the array contain all the given items? Length of the array must match the number of matchers, but their order is not important.

@Test
public void arrayContainingInAnyOrderMatcherExample() {

    String[] names = {"Jon", "Peter", "Paul"};
    assertThat(names, is(arrayContainingInAnyOrder("Peter", "Paul", "Jon")));
}
  • arrayWithSize()

Does the input array have exactly the specified length?

@Test
public void arrayWithSizeMatcherExample() {

    String[] names = {"Jon", "Peter", "Paul"};
    assertThat(names, is(arrayWithSize(3)));
}
@Test
public void arrayWithSizeGreaterThanMatcherExample() {

    String[] names = {"Jon", "Peter", "Paul"};
    assertThat(names, is(arrayWithSize(greaterThan(2))));
}
  • closeTo()

Matcher which can be used with either Double or BigDecimal to check if a value is within a specified error margin of an expected value.

@Test
public void closeToDoubleMatcherExample() {

    Double temperature = 25.5;
    assertThat(temperature, closeTo(25.0, 0.5));
}
@Test
public void closeToBigDecimalMatcherExample() {

    BigDecimal totalValue = new BigDecimal(234.00);
    assertThat(totalValue, closeTo(new BigDecimal(230.0), new BigDecimal(5)));
}