Skip to content

Instantly share code, notes, and snippets.

@hschafer
Last active February 4, 2019 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hschafer/e64ca794712100cac20095afd9ecc7de to your computer and use it in GitHub Desktop.
Save hschafer/e64ca794712100cac20095afd9ecc7de to your computer and use it in GitHub Desktop.

I'm a frayed you don't remember Strings

The next assignment deals with a lot of manipulations of Strings, so this example should help remind everyone how to work with Strings in their programs.

I want to write a method called dashes that takes a String and puts dashes between all the characters. If the given String is null, the method should throw an IllegalArgumentException. For example, the call

System.out.println(dashes("hello")); // Output: h-e-l-l-o

First attempt

public static String dashes(String word) {
    if (word.isEmpty()) {
        throw new IllegalArgumentException();
    }

    // initialize to empty String
    String result = "";
    char[] chars = word.toCharArray();
    // standard loop over characters in String
    for (int i = 0; i < chars.length; i++) {
        // build up dash and character
        result += chars[i] + "-";
    }
    return result;
}

The above code has two correctness errors and one stylistic error, can you figure out what they are?

================================================|
|                                               |
|                                               |
|                                               |
|   TRY TO SPOT THE ERRORS BEFORE READING ON    |
|                                               |
|                                               |
|                                               |
================================================|
  • Correctness: Does not correctly check for null for the IllegalArgumentException
    • Students commonly mix up the "empty String" ("") and the "null String" (null). An empty String "" is a String that has no characters while the null String null is the absence of the String at all. If you think of Strings like boxes that hold characters, the empty String is a box that is empty while the null String is a box that doesn't exist. The proper check would be if (word == null)
  • Correctness: There are too many dashes in the result! dashes("hello") => "h-e-l-l-o-". The fix is described below.
  • Style: Unnecessarily creates an extra object when calling toCharArray. There is no need to create this array of characters since we have access to the characters in the String using the charAt method.

This is a classic example of a fence-post problem. Where we have n characters and want to place n-1 characters we want to place between them. Many people call this a fence-post because we are trying to build something like a fence as can be seen in the figure below

|-|-|-|-|

Fencepost problem:
    Posts = | (characters)
    Links = - (dashes)

However our code places a "post" and a "link" on each iteration and doesn't take into account that there are a different number of "posts" and "links". One way to solve this is to pull part of an iteration outside the loop and then flip the order inside the loop.

public static String dashes(String word) {
    if (word == null) {
        throw new IllegalArgumentException();
    }

    String result = "" + word.charAt(0);       // Note: Have to do `"" + ...` to turn the character into a String
    for (int i = 1; i < word.length(); i++) {  // Note: Starting at 1
        result += "-" + word.charAt(i);        // Note: Swapped order of fence and post
    }
    return result;
}

This solution almost works, except in one case when given the empty String "". To fix this we could add a special case at the beginning or add a pre-condition to the method saying we don't handle those Strings (as long as that doesn't break the spec we were asked to implement).

Below is an alternative way of solving the problem that some people prefer

public static String dashes(String word) {
    if (word == null) {
        throw new IllegalArgumentException();
    }

    String result = "";
    for (int i = 0; i < word.length(); i++) {
        result += "-" + word.charAt(i);
    }
    // Still doesn't work if word is the empty String!
    return result.substring(1);
}

Collections

This assignment asks you to work with the Collection interface. Many students haven't seen this interface before, but it is nothing really new since it is the generalization of things like Set and List; in fact Set and List are both interfaces that satisfy the Collection interface (more on this towards the end of the quarter). If you are working with a Collection, you have access to the following methods; there are more methods in the actual Java specification, but you probably won't use them.

Method Description
add(value) adds the given value to this collection
addAll(other) adds every value from the other collection to this one
clear() removes all the values from this collection
contains(value) returns true if the value is in this collection, false otherwise
isEmpty() returns true if and only if there are no values in this collection
iterator() returns an Iterator to access the elements in this collection
remove(value) removes the given value from this collection
size() returns the number of elements in this collection

Have any feedback about this reading? Please let us know using this form.

Copyright © 2019 Hunter Schafer and Porter Jones. All rights reserved. Permission is hereby granted to students registered for University of Washington CSE 143 for use solely during Winter Quarter 2019 for purposes of the course. No other use, copying, distribution, or modification is permitted without prior written consent. Copyrights for third-party components of this work must be honored. Instructors interested in reusing these course materials should contact the authors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment