DEV Community

Cover image for Getting the Gist of Java
Andrew (he/him)
Andrew (he/him)

Posted on

Getting the Gist of Java

or

I Had A Very Busy Weekend

To catch up on a backlog of work for an upcoming deadline, I spent most of this past weekend coding (writing new stuff and fixing up old projects). Check out some of these Gists I wrote and gimme those sweet, sweet stars:

  1. PNode - yet another tree structure for Java
  2. Typifier - parse the String representation of an object into one of Java's primitive wrapper classes (also LocalDateTime for timestamps)
  3. ExpandPath - interprets ~ or ~user home directories, %ENVIRONMENT% $VARIABLES, and gl*bs to return lists of files, on both Windows and Linux.
  4. SplitXSV - splits a line of sentinel-separated text and returns the result
  5. Maven-With-Resources - a small example repo to show how to read src/main/resources/ files within the code of a Maven project
  6. ParseFileName - parse a file name and return the path, filename itself, and extension (if it exists) in a String[].
  7. ParseCLArgs - parse command-line arguments and categorize as standard arguments or flags

See short descriptions and examples of these projects below:


PNode

There is no shortage of custom-made tree structures written in Java, probably because the best implementation only exists in the javax.swing package, which is now de facto deprecated, replaced by JavaFX. So I wrote a tree (or rather a node) class where each node has a label and a value (both or either of which can be null). The nodes are kept track of via their indices in Lists, which means when a node is "deleted", it's replaced by a null to maintain List indexing.

Original tree:

    0 |-- n01_label
    1 |    |-- n02_label
    2 |    |    |-- n04_label
    2 |    |    |-- n05_label
    3 |    |         |-- n08_label
    1 |    |-- n03_label
    2 |         |-- n06_label
    2 |         |-- n07_label


Tree after orphaning n05:

    0 |-- n01_label
    1 |    |-- n02_label
    2 |    |    |-- n04_label
    1 |    |-- n03_label
    2 |         |-- n06_label
    2 |         |-- n07_label


n05 tree after orphaning n05:

    0 |-- n05_label
    1 |    |-- n08_label


Tree after adopting n05:

    0 |-- n01_label
    1 |    |-- n02_label
    2 |    |    |-- n04_label
    1 |    |-- n03_label
    2 |    |    |-- n06_label
    2 |    |    |-- n07_label
    1 |    |-- n05_label
    2 |         |-- n08_label

Enter fullscreen mode Exit fullscreen mode

Typifier

Often, when parsing text files, you want to determine the type of data represented by the Strings you're reading in. Typifier allows interpretation of String data as any of Java's primitive wrapper types, boxing data in the narrowest type possible. The code also allows for the user to define timestamp formats so that Strings can be parsed as LocalDateTime objects as well! To speed up processing of large data sets, interpretation can be restricted to "common" types only (Double, Boolean, LocalDateTime, String).

String.trim() is used to remove leading and trailing whitespace, so the following work fine:

  typify (" 23 ") => "23" [Byte]
  typify ("     3.4 ") => "3.4" [Float]

But if the user enters only whitespace, that's fine, too:

  typify (" ") => " " [String]
  typify ("    ") => "    " [String]

The user can choose to interpret 1/0 as true/false:

  typify ("1") => "true" [Boolean]
  typify ("true") => "true" [Boolean]
  typify ("0") => "false" [Boolean]

Ranges of Byte, Short, and Float are used to box the value in the narrowest type available:

  typify (" 2 ") => "2" [Byte]
  typify (" 200 ") => "200" [Short]
  typify ("2e9 ") => "2.0E9" [Float]
  typify (" 2e99") => "2.0E99" [Double]

If String has length 1 and is not Boolean or Byte, it will be assigned the Character type:

  typify ("4") => "4" [Byte]
  typify ("-") => "-" [Character]
  typify ("a") => "a" [Character]

Dates can also be parsed, and formats can be defined by the user:

  typify ("2014-12-22 14:35:22") => "2014-12-22 14:35:22" [LocalDateTime]
  typify ("3/5/99 6:30") => "3/5/99 6:30" [LocalDateTime]

Enter fullscreen mode Exit fullscreen mode

ExpandPath

Passing lists of files via the command line to a Java program doesn't always work as expected. The shell can auto-expand $ENVIRONMENT_VARIABLES or gl*bs, and lots of features available in bash aren't available in the Windows cmd.exe prompt. This script allows for paths to be interpreted the same way on Windows and Unix and adds recursive "double-globbing" (**) to pre-bash4 shells (as well as cmd), among other cool features.

C:\>java ExpandPath "~/test/**.txt"

arg: '~/test/**.txt'

  C:\Users\andrew.watson\test\a\d\a.txt
  C:\Users\andrew.watson\test\b\d\e.txt
  C:\Users\andrew.watson\test\a\d\d.txt
  C:\Users\andrew.watson\test\a.txt
  C:\Users\andrew.watson\test\c\c.txt
  C:\Users\andrew.watson\test\1.txt
  C:\Users\andrew.watson\test\b\d\a.txt
  C:\Users\andrew.watson\test\b\b.txt
  C:\Users\andrew.watson\test\b\d\f.txt
  C:\Users\andrew.watson\test\0.txt
  C:\Users\andrew.watson\test\a\a.txt
  C:\Users\andrew.watson\test\b\a.txt
Enter fullscreen mode Exit fullscreen mode

SplitXSV

This script splits a line of sentinel-separated text and returns the resulting tokens. Any non-alphanumeric character is preceded with a '\' to escape it, so even tabs or line breaks can be used as the delimiters.

given sentinel: '-'

given string:
{1-800-944-2345}

result:
{1}, {800}, {944}, {2345}

----------

given sentinel: ' '

given string:
{hi how are you}

result:
{hi}, {how}, {are}, {you}

Enter fullscreen mode Exit fullscreen mode

Maven-With-Resources

It can be frustrating to try to figure out how to read "resource" files in the code of a Maven project. There are differing and contradictory answers online. For posterity, I've set up a MWE Maven Project that shows how to read files located at src/main/resources and use those files in your Java code.

GitHub logo awwsmm / Maven-With-Resources

Easily read files from src/main/resources in your Maven project

Using Resource Files in a Maven Project

Run the following command to generate a blank Maven project:

mvn -B archetype:generate \
  -DarchetypeGroupId=org.apache.maven.archetypes \
  -DgroupId=com.companyname.packagename \
  -DartifactId=my-new-package
Enter fullscreen mode Exit fullscreen mode

It will make a new directory called "my-new-package" inside the current directory. Next, make a directory called src/main/resources inside the Maven project directory (inside my-new-package) and add the following text to a file called example.txt in that directory:

this is an example resource
here is a second line
and a third one

Remove the files src/test/java/com/companyname/packagename/AppTest.java and src/main/java/com/companyname/packagename/App.java. Replace the text of your pom.xml file with the following text:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/maven-v4_0_0.xsd"&gt
  <modelVersion>4.0.0</modelVersion>

  <groupId>     com.companyname.packagename  </groupId>
  <artifactId>  my-new-package               </artifactId>
  <packaging>   jar                          </packaging>

  <version
Enter fullscreen mode Exit fullscreen mode

ParseFileName

This short script is useful for quickly getting the containing directory of a file or its extension. The user can them selectively process files based on those attributes.

The lines:

    System.out.println(Arrays.toString(parseFileName("test").get()));
    System.out.println(Arrays.toString(parseFileName("test.a").get()));
    System.out.println(Arrays.toString(parseFileName("test.a.b").get()));

...yield the output:

[/home/andrew, test, ]
[/home/andrew, test, a]
[/home/andrew, test, a.b]
Enter fullscreen mode Exit fullscreen mode

ParseCLArgs

This is another short script that parses command-line arguments as basic ARGUMENTs, FLAGs (like -this), LONGFLAGs (like --this), or OTHER (only - or --). The arguments are returned in-order in a List so the user can determine whether or not the provided flags and arguments are valid.

$ java ParseCLArgs arg -short anotherArg --long - -- ---toolong
ARGUMENT=arg
FLAG=short
ARGUMENT=anotherArg
LONGFLAG=long
OTHER=-
OTHER=--
LONGFLAG=-toolong
Enter fullscreen mode Exit fullscreen mode

So there you have it! That's how much coding you can get done in one weekend if you do nothing else but eat and sleep. 0/10 would not recommend.

Top comments (0)