Wednesday, July 13, 2016

Enums in Java

If you're familiar with C or C++, you may tend to think of enums as just integers. Which they basically are - in those languages, but not in Java.
Java enum is a special kind of class. What's the difference for you as a user?

It you just want a simple enum and don't care about real values behind enum constants, you can go ahead and just do as in old good C (almost, as C syntax is slightly different):
enum Color {RED, GREEN, YELLOW}
 . . .
Colors col = RED;
But if you try to assign an integer value to col, as you could in C, like so:
col = 2;
- the code fails to compile, which is a good thing, as you obviously want your value to be one of the predefined constants.
Well, actually you can't compile this in C++ either, but you can still force the compiler to build it by using a cast like this one:
col = (Color)2;
But that's beside the point. If you want your constants to have specific values, in C you could achieve that like this (note that this is C syntax, which is slightly different from Java):
enum Color {RED=5, YELLOW=10, GREEN=15};
If you want this in Java, you have to take into account that your enum is going to be a special kind of Java class, extending java.lang.Enum. Its syntax is also different from both C / C++ enums and normal Java classes:
enum Color
{
    RED(5), GREEN(10), YELLOW(15);
    private int col;
    private Color(int col) { this.col = col; }
    private int getValue() { return col; }
}
And this is how you use it:
Color c = Color.RED;
System.out.println(c);
which prints out
RED
But you can't just go and assign an integer value to your enum object:
Color c = 5;
System.out.println(c);
because
error: incompatible types: int cannot be converted to Color

There's much more to Java enums, check out these links for more details:

Monday, July 11, 2016

java.time

java.time is a package for handling date / time values, introduced in Java 8. Before that you had to use classes like java.util.Date or java.sql.Date, if you were dealing with SQL databases.

These are still available in Java 8, but I would rather avoid them, as they're not thread safe, don't support the notion of time zones, etc. You can use a third-party solution like Joda-Time, but if you're writing Java 8 code, I see no reason not to use buiilt-in java.time.

Here's an article from Java Magazine, introducing java.time package.

I myself am most interested in ZonedDateTime class, as it represents timestamp in a certain time zone. ZonedDateTime (like OffsetDateTime class) contains at its heart an object of Instant class, and time zone information.

Instant is "an instantaneous point on the time-line", in other words it's just a number of seconds (and nanoseconds) passed since "epoch" (1970-01-01T00:00:00Z). This value doesn't depend on time zone, it is the same no matter where in the world you are (java.time doesn't take relativity into account, which is fine with me).

What this means, basically, is that you can't "convert" ZonedDateTime to another time zone, but what you can do instead is create another ZonedDateTime object with the same Instant value, but with different time zone setting. You can't change your existing ZonedDateTime objects, since they are immutable (thread safety!).

Using ZonedDateTime.withZoneSameInstant does just that:
import java.time.ZoneId;
import java.time.ZonedDateTime;

. . .

ZonedDateTime zdtHereNow = ZonedDateTime.now();
System.out.println("ZonedTimeDate here and now = " + zdtHereNow);

ZoneId utcTzId = ZoneId.of("UTC");
ZonedDateTime zdtUtcNow = zdtHereNow.withZoneSameInstant(utcTzId);
System.out.println("ZonedTimeDate \"here and now\" in UTC = " + zdtUtcNow);

Redis + Java = Jedis

"Jedis is a blazingly small and sane Redis java client."

Jedis wiki is here - https://github.com/xetorthio/jedis/wiki

Here's a tutorial: http://www.tutorialspoint.com/redis/redis_java.htm

If you want to download Jedis jar (compiled, not the source zip they offer on their Github page), use this link - http://repo1.maven.org/maven2/redis/clients/jedis/
Go to the folder with the greatest version number (currently 2.8.1, but it'll change) and download jedis-.jar (jedis-2.8.1.jar at the moment).

Don't forget to add this jar to your CLASSPATH both for javac (when you compile your project) and for java (when you run it).

Another option, besides Jedis, is Lettuce - see here for short introductions for both Lettuce and Jedis.

Finally, here's a small example of my own:

package kotodemo.jedis_test;

import java.util.Set;
import redis.clients.jedis.Jedis;

class JedisTest1
{
 public static void main(String[] args)
 {
  // Connecting to Redis server on localhost
  Jedis jedis = new Jedis("localhost", 6100); // Note the non-standard port 6100 I'm using
  // Check whether server is running or not
  System.out.println("Server is running: " + jedis.ping());

  // Get the names of all the keys print them
  Set keys = jedis.keys("*");
  for(String keyStr : keys)
   System.out.println(keyStr);
 }
}

Update: to connect to a non-zero Redis database, use Redis URI to initialize Jedis object, like so:
import java.net.URI;
. . .
Jedis jedis = new Jedis(new URI("redis://localhost:6100/7"));
where 6100 is Redis port I used to test this particular code snippet and 7 is Redis DB I wanted to connect to.

More information on Redis URIs (URLs):

Sunday, July 10, 2016