Setup a MacBook Java Development Environment

As we’ve become more mobile it’s important to enable our travel work stations to handle a multitude of development environments. Most developers will want to setup a Java SE development kit on their laptop. This is a step-by-step walkthrough outlining the elements necessary to develop Java applications on your iMac, MacBook, or any OS X device.

Step 1 : Install Java Development Kit (JDK)

Java SE Development Kit 8
Download the MAC OS X installation file jdk-Bu121-macosx-x64.dmg (233 MB).

java development kit installation

Step 2 : Setup JAVA_HOME Environment Variable

If you’ve never setup a bash profile open up Terminal and enter:
cd ~/

This will take you to the root directory. Then type:
touch .bash_profile to create the new file.

I personally prefer to edit files in Terminal using Vim editor:
vim .bash_profile

When the editor opens, the file should be blank. Press V then I to activate editing and copy and paste the following line into the file:
export JAVA_HOME=$(/usr/libexec/java_home)

To exit the editor and save the document press ESC and then type a colon : ( shift + : ) which will bring up a colon : at the bottom of the file. Now type in wq! and hit ENTER. This will save the .bash_profile file with your new JAVA_HOME entry.

Lastly, type:
. .bash_profile
This will reload .bash_profile and update the function we just added.

To check our work type in:
source .bash_profile
This should display:

You can skip all of step 3 by installing Homebrew.
I recommend installing it as you will need it down the road to install other environments.
To install Homebrew via SSH type the following line into terminal:

/usr/bin/ruby -e "$(curl -fsSL"

Now that you have Homebrew installed you can install Apache Maven:
brew install maven

Check you have Maven installed by entering:
mvn -version

Now you can skip Step 3A and go to Step 3B.

Step 3A : Install Apache Maven

Go to Apache’s Website here: Apache Maven

Then download the source zip archive file found halfway down the page:
Apache Maven Install File

Step 3B : Setup Maven Symbolic Link

I recommend making a symbolic link to the Maven installation folder inside of an opt folder by entering the following:
First create the folder name “opt”
mkdir opt
Enter the opt folder:
cd opt
Create a folder named “maven”
mkdir maven
Now go back one folder:
cd ..
Lastly, make a symbolic link inside the maven folder by typing the following:
ln -s ~/apache-maven-3.5.0 ~/opt/maven

Then we will go into our .bach_profile file:
vim ~/.bash_profile

Add the following 3 lines into the file (after our previously added JAVA_HOME line).

export M2_HOME=/path/to/maven
export M2=$M2_HOME/bin
export PATH=$M2:$PATH

Remember to close the file using wq! to save changes.

Now type:
. .bash_profile
To initialize those changes.

Step 4 : Install GCC and GIT

There are a couple different ways to install Git and the GNU Compiler Collection GCC.
The easiest is to install Homebrew

brew install gcc
brew install git

Grab a brew because this is gonna take some time to install.

Step 5 : Install IntelliJ IDEA

A Java IDE (Integrated Development Environment) is a software application which enables you to easily write and debug Java programs. IntelliJ provides features like syntax highlighting and code completion. Some popular ones include Eclipse, NetBeans, ItelliJ IDEA, JDeveloper and Android Studio.

I’m going to have you install IntelliJ IDEA (418 MB) from their download page

After the zip file has downloaded, unzip it and drag the file into your Application folder.

You are now technically done! Launch IntelliJ and start developing the next big application.

Here are some extras you can install to add more features to your JAVA development environment.

NodeJS – Download Page
I’m brave so I installed the latest version 7.9.0 but you can choose to install the most stable version 6.10.2 if you feel that suits you better. The difference between the stable and latest version is you may experience issues with the latest version that are due to its current code.

Java String Q&A

I’ve made a list of some common Java String questions I receive starting from extremely basic to more advanced questions.

What is String in Java?

String is a Class in java and defined in java.lang package. It’s not a primitive data type like int and long. String class represents character Strings. String is used in almost every Java application.

String str = new String("abc");
String str1 = "abc";

Further Use:
Here is an example method that will remove a given character from a String.

 private static String removeChar(String str, char c) {
        if (str == null)
            return null;
        return str.replaceAll(Character.toString(c), "");

Why using Char array for password storage is better than using String?

String is immutable in java and stored in String pool. Once it’s created it stays in the pool until garbage is collected, so even when we’re finished with a password it is still available in memory, and we don’t want that. This means anyone with access to the memory dump will have access to it, a big security no no.

So, by using char array for password storage, we can set it to blank once we are done with it. Also we can control how long it’s available in memory thus avoiding the security threat.

How do you check if two Java Strings are equal?

There are two ways to check if two Strings are equal or not – using “==” operator or using equals method. When we use “==” operator, it checks for value of String as well as reference but in our programming, most of the time we are checking equality of String for value only. So we should use equals method to check if two Strings are equal or not.
There is another function equalsIgnoreCase that we can use to ignore case.

String s1 = "sethcodes";
String s2 = "sethcodes";
String s3 = new String("sethcodes");
System.out.println("s1 == s2 ? "+(s1==s2)); //true
System.out.println("s1 == s3 ? "+(s1==s3)); //false
System.out.println("s1 equals s3 ? "+(s1.equals(s3))); //true

What does the String intern() method do?

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
This method always return a String that has the same contents as this string, but is guaranteed to be from a pool of unique strings.

Java Connect to Remote Database through SSH using Port Forwarding

There may be a time when you need to connect to a remote database using an SSH connection. Here is an example of using port forwarding to connect remotely. This example is for MySQL but you can use it for almost any database.

import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.sql.Connection;
public class MySqlConnOverSSH {
    public static void main(String[] args) throws SQLException {
        int lport=5656;
        String rhost="";
        String host="";
        int rport=3306;
        String user="sshuser";
        String password="sshpassword";
        String dbuserName = "mysql";
        String dbpassword = "mysql123";
        String url = "jdbc:mysql://localhost:"+lport+"/mydb";
        String driverName="com.mysql.jdbc.Driver";
        Connection conn = null;
        Session session= null;
            //Set StrictHostKeyChecking property to no to avoid UnknownHostKey issue
            java.util.Properties config = new java.util.Properties(); 
            config.put("StrictHostKeyChecking", "no");
            JSch jsch = new JSch();
            session=jsch.getSession(user, host, 22);
            int assinged_port=session.setPortForwardingL(lport, rhost, rport);
            System.out.println("localhost:"+assinged_port+" -> "+rhost+":"+rport);
            System.out.println("Port Forwarded");
            //mysql database connectivity
            conn = DriverManager.getConnection (url, dbuserName, dbpassword);
            System.out.println ("Database connection established");
        }catch(Exception e){
            if(conn != null && !conn.isClosed()){
                System.out.println("Closing Database Connection");
            if(session !=null && session.isConnected()){
                System.out.println("Closing SSH Connection");

Write to MySQL Database Using Java

Probably one of the most common tasks you’ll ever utilize is writing to a database. Java INSERT is a very basic code snippet. This code inserts a first and last name into the table.

create table users (
  id int unsigned auto_increment not null,
  first_name varchar(32) not null,
  last_name varchar(32) not null,
  date_created timestamp default now(),
  is_admin boolean,
  num_points int,
  primary key (id)

Just for your reference here is another way to write to a MySQL database using JavaScript. Note: I’ve got the database host set to “localhost” since we are executing the script on the same server. The username is set to “root”.

This script will be inserting a first name, last name, and date created etc. I created a Prepared Statement to capture all the values before executing the write.

import java.sql.*;
import java.util.Calendar;

public class JavaMysqlPreparedStatementInsertExample

  public static void main(String[] args)
      // create a mysql database connection
      String myDriver = "";
      String myUrl = "jdbc:mysql://localhost/test";
      Connection conn = DriverManager.getConnection(myUrl, "root", "");
      // create a sql date object so we can use it in our INSERT statement
      Calendar calendar = Calendar.getInstance();
      java.sql.Date startDate = new java.sql.Date(calendar.getTime().getTime());

      // the mysql insert statement
      String query = " insert into users (first_name, last_name, date_created, is_admin, num_points)"
        + " values (?, ?, ?, ?, ?)";

      // create the mysql insert preparedstatement
      PreparedStatement preparedStmt = conn.prepareStatement(query);
      preparedStmt.setString (1, "Barney");
      preparedStmt.setString (2, "Rubble");
      preparedStmt.setDate   (3, startDate);
      preparedStmt.setBoolean(4, false);
      preparedStmt.setInt    (5, 5000);

      // execute the preparedstatement
    catch (Exception e)
      System.err.println("Got an exception!");

Now that you’ve written to the database you can query it using the following script:

select * from users;

The output should resemble this:

| id | first_name | last_name | date_created        | is_admin | num_points |
|  1 | Barney     | Rubble    | 2010-06-23 14:02:00 |        0 |       5000 | 
1 row in set (0.00 sec)

Java Standard Collections

In the Collections Framework, there are many implementation classes to choose from. Most of the time, one of these “primary implementations” is the appropriate choice

Before JDK 1.5, HashMap and HashSet were the preferred implementations of Map and Set. However, the iterators returned by those classes have the somewhat bizarre property of having an undefined order. That is, iterating over a HashMap or HashSet can return elements in a different order at different times. Their iteration order is not guaranteed to be repeatable (and often isn’t). Even though HashMap and HashSet have slightly better overall performance, for most business applications it is likely best to avoid such undefined behavior.

To retain the sorting of items being manipulated in a graphical user interface, TreeSet and TreeMapare useful. They force a collection to maintain a sort order when the user adds and deletes items.


Collections Framework Overview


The Java platform includes a collections framework. A collection is an object that represents a group of objects (such as the classic Vector class). A collections framework is a unified architecture for representing and manipulating collections, enabling collections to be manipulated independently of implementation details.

The primary advantages of a collections framework are that it:

  • Reduces programming effort by providing data structures and algorithms so you don’t have to write them yourself.
  • Increases performance by providing high-performance implementations of data structures and algorithms. Because the various implementations of each interface are interchangeable, programs can be tuned by switching implementations.
  • Provides interoperability between unrelated APIs by establishing a common language to pass collections back and forth.
  • Reduces the effort required to learn APIs by requiring you to learn multiple ad hoc collection APIs.
  • Reduces the effort required to design and implement APIs by not requiring you to produce ad hoc collections APIs.
  • Fosters software reuse by providing a standard interface for collections and algorithms with which to manipulate them.

The collections framework consists of:

  • Collection interfaces. Represent different types of collections, such as sets, lists, and maps. These interfaces form the basis of the framework.
  • General-purpose implementations. Primary implementations of the collection interfaces.
  • Legacy implementations. The collection classes from earlier releases, Vector and Hashtable, were retrofitted to implement the collection interfaces.
  • Special-purpose implementations. Implementations designed for use in special situations. These implementations display nonstandard performance characteristics, usage restrictions, or behavior.
  • Concurrent implementations. Implementations designed for highly concurrent use.
  • Wrapper implementations. Add functionality, such as synchronization, to other implementations.
  • Convenience implementations. High-performance “mini-implementations” of the collection interfaces.
  • Abstract implementations. Partial implementations of the collection interfaces to facilitate custom implementations.
  • Algorithms. Static methods that perform useful functions on collections, such as sorting a list.
  • Infrastructure. Interfaces that provide essential support for the collection interfaces.
  • Array Utilities. Utility functions for arrays of primitive types and reference objects. Not, strictly speaking, a part of the collections framework, this feature was added to the Java platform at the same time as the collections framework and relies on some of the same infrastructure.

Collection Interfaces

The collection interfaces are divided into two groups. The most basic interface, java.util.Collection, has the following descendants:

The other collection interfaces are based on java.util.Map and are not true collections. However, these interfaces contain collection-view operations, which enable them to be manipulated as collections. Map has the following offspring:

Many of the modification methods in the collection interfaces are labeled optional. Implementations are permitted to not perform one or more of these operations, throwing a runtime exception (UnsupportedOperationException) if they are attempted. The documentation for each implementation must specify which optional operations are supported. Several terms are introduced to aid in this specification:

  • Collections that do not support modification operations (such as add, remove and clear) are referred to as unmodifiable. Collections that are not unmodifiable are modifiable.
  • Collections that additionally guarantee that no change in the Collection object will be visible are referred to as immutable. Collections that are not immutable are mutable.
  • Lists that guarantee that their size remains constant even though the elements can change are referred to as fixed-size. Lists that are not fixed-size are referred to asvariable-size.
  • Lists that support fast (generally constant time) indexed element access are known as random access lists. Lists that do not support fast indexed element access are known as sequential access lists. The RandomAccess marker interface enables lists to advertise the fact that they support random access. This enables generic algorithms to change their behavior to provide good performance when applied to either random or sequential access lists.

Some implementations restrict what elements (or in the case of Maps, keys and values) can be stored. Possible restrictions include requiring elements to:

  • Be of a particular type.
  • Be not null.
  • Obey some arbitrary predicate.

Attempting to add an element that violates an implementation’s restrictions results in a runtime exception, typically a ClassCastException, an IllegalArgumentException, or a NullPointerException. Attempting to remove or test for the presence of an element that violates an implementation’s restrictions can result in an exception. Some restricted collections permit this usage.

Collection Implementations

Classes that implement the collection interfaces typically have names in the form of <Implementation-style><Interface>. The general purpose implementations are summarized in the following table:

Interface Hash Table Resizable Array Balanced Tree Linked List Hash Table + Linked List
Set HashSet TreeSet LinkedHashSet
List ArrayList LinkedList
Deque ArrayDeque LinkedList
Map HashMap TreeMap LinkedHashMap

The general-purpose implementations support all of the optional operations in the collection interfaces and have no restrictions on the elements they may contain. They are unsynchronized, but the Collections class contains static factories called synchronization wrappers that can be used to add synchronization to many unsynchronized collections. All of the new implementations have fail-fast iterators, which detect invalid concurrent modification, and fail quickly and cleanly (rather than behaving erratically).

The AbstractCollection, AbstractSet, AbstractList, AbstractSequentialList and AbstractMap classes provide basic implementations of the core collection interfaces, to minimize the effort required to implement them. The API documentation for these classes describes precisely how each method is implemented so the implementer knows which methods must be overridden, given the performance of the basic operations of a specific implementation.

Concurrent Collections

Applications that use collections from more than one thread must be carefully programmed. In general, this is known as concurrent programming. The Java platform includes extensive support for concurrent programming. See Java Concurrency Utilities for details.

Collections are so frequently used that various concurrent friendly interfaces and implementations of collections are included in the APIs. These types go beyond the synchronization wrappers discussed previously to provide features that are frequently needed in concurrent programming.

These concurrent-aware interfaces are available:

The following concurrent-aware implementation classes are available. See the API documentation for the correct usage of these implementations.

Design Goals

The main design goal was to produce an API that was small in size and, more importantly, in “conceptual weight.” It was critical that the new functionality not seem too different to current Java programmers; it had to augment current facilities, rather than replace them. At the same time, the new API had to be powerful enough to provide all the advantages described previously.

To keep the number of core interfaces small, the interfaces do not attempt to capture such subtle distinctions as mutability, modifiability, and resizability. Instead, certain calls in the core interfaces are optional, enabling implementations to throw an UnsupportedOperationException to indicate that they do not support a specified optional operation. Collection implementers must clearly document which optional operations are supported by an implementation.

To keep the number of methods in each core interface small, an interface contains a method only if either:

  • It is a truly fundamental operation: a basic operations in terms of which others could be reasonably defined,
  • There is a compelling performance reason why an important implementation would want to override it.

It was critical that all reasonable representations of collections interoperate well. This included arrays, which cannot be made to implement the Collection interface directly without changing the language. Thus, the framework includes methods to enable collections to be moved into arrays, arrays to be viewed as collections, and maps to be viewed as collections.