Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
interfacesAbstractClasses.xml 55.28 KiB
<?xml version="1.0" encoding="UTF-8"?>
<chapter annotations="slide" version="5.1"
         xml:id="sd1_chap_interfacesAbstractClasses"
         xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:svg="http://www.w3.org/2000/svg"
         xmlns:ns="http://docbook.org/ns/transclusion"
         xmlns:m="http://www.w3.org/1998/Math/MathML"
         xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns:db="http://docbook.org/ns/docbook">
  <title><code language="java">interface</code> definitions and <code
  language="java">abstract</code> Classes</title>

  <figure xml:id="sd1_interface_fig_ethernetInterfaces">
    <title>Interface examples</title>

    <mediaobject>
      <imageobject>
        <imagedata fileref="Ref/Interfaces/interfacePrinciple.multi.svg"/>
      </imageobject>
    </mediaobject>
  </figure>

  <figure xml:id="sd1_interface_fig_ethernetInterfaceObservations">
    <title>Observations</title>

    <para>Multiple standards involved:</para>

    <glosslist>
      <glossentry>
        <glossterm><link
        xlink:href="https://en.wikipedia.org/wiki/Modular_connector#8P8C_(8_position_8_contact)">8P8C</link></glossterm>

        <glossdef>
          <para>Mechanical dimensions and tolerances.</para>
        </glossdef>
      </glossentry>

      <glossentry>
        <glossterm><link
        xlink:href="https://en.wikipedia.org/wiki/ISO/IEC_11801#Category_7">CAT7</link></glossterm>

        <glossdef>
          <para>Telecommunication performance of twisted-pair copper
          interconnects.</para>
        </glossdef>
      </glossentry>
    </glosslist>

    <para>Note: Compatible hardware must obey <emphasis
    role="red">both</emphasis> standards.</para>
  </figure>

  <figure xml:id="sd1_interface_fig_text2file">
    <title>Writing strings to file</title>

    <programlisting language="java">public class Text2File {
  private final PrintStream out;

  public Text2File(final String fileName)
     throws FileNotFoundException {
    out = new PrintStream(new File(fileName));}

  public void println(final String s) {
    out.println(s);}

  public void closeFile() {
    out.close();}
}</programlisting>
  </figure>

  <figure xml:id="sd1_interface_fig_usingText2file">
    <title>Using <classname>Text2File</classname></title>

    <informaltable border="0">
      <tr>
        <td valign="top"><programlisting language="java">final String outputFileName =
            "output.txt";
try {
  final Text2File output =
  new Text2File(outputFileName);
  output.println("Some dumb text");
  output.println("More dumb text");
  output.closeFile();
} catch (final FileNotFoundException e){
  System.err.println("Unable to open '"
   + outputFileName + "' for writing");
}</programlisting></td>

        <td valign="top"><para>File
        <filename>output.txt</filename>:</para><screen>Some dumb text
More dumb text</screen></td>
      </tr>
    </informaltable>
  </figure>

  <figure xml:id="sd1_interface_fig_usingText2fileProblem">
    <title>Possible <classname>Text2File</classname> errors:</title>

    <itemizedlist>
      <listitem>
        <para>Missing <code language="java">output.closeFile()</code>
        call.</para>

        <para>Some text portion may not be flushed to disk.</para>
      </listitem>

      <listitem>
        <para>Calling <code language="java">output.println(...)</code> after
        <code language="java">output.closeFile()</code>:</para>

        <programlisting language="java">output.closeFile();
output.println("Too late!");</programlisting>

        <para>Last call will be silently ignored.</para>
      </listitem>
    </itemizedlist>
  </figure>

  <figure xml:id="sd1_interface_fig_Text2fileProblemPartialSolution">
    <title>Employ <quote>try-with-resources</quote></title>

    <informaltable border="0">
      <tr>
        <td valign="top"><programlisting language="java">final String outputFileName =
     "output.txt";

try (final Text2File output =
     new Text2File(outputFileName)){
  output.println("Some dumb text");
  output.println("More dumb text");
} catch (FileNotFoundException e){...}</programlisting></td>

        <td valign="top"><para>Compile time error:</para><screen>Required:
   <link xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/AutoCloseable.html">java.lang.AutoCloseable</link>
Found:
  de.hdm_stuttgart.mi.sd1.Text2File</screen></td>
      </tr>
    </informaltable>
  </figure>

  <figure xml:id="sd1_interface_fig_interfaceSyntax">
    <title><code language="java">interface</code> syntax</title>

    <programlisting language="java">accessModifier interface interfaceName [throwsClause]?{
    [field]*
   [method]*
}</programlisting>
  </figure>

  <figure xml:id="sd1_interface_fig_AutoCloseablePromise">
    <title>The <classname
    xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/AutoCloseable.html">AutoCloseable</classname>
    promise</title>

    <informaltable border="0">
      <tr>
        <td valign="top"><programlisting language="java">package java.lang; <co
              linkends="sd1_interface_fig_AutoCloseablePromise-1.2"
              xml:id="sd1_interface_fig_AutoCloseablePromise-1.2-co"/>

public interface AutoCloseable {

/**
 * Closes this resource,
 * relinquishing any
 * underlying resources.
 */
void close​() <co linkends="sd1_interface_fig_AutoCloseablePromise-2.2"
              xml:id="sd1_interface_fig_AutoCloseablePromise-2.2-co"/>;

}</programlisting></td>

        <td valign="top"><programlisting language="java">public class Text2File
  implements AutoCloseable <co
              linkends="sd1_interface_fig_AutoCloseablePromise-1"
              xml:id="sd1_interface_fig_AutoCloseablePromise-1-co"/>{

  private <co linkends="sd1_interface_fig_AutoCloseablePromise-2"
              xml:id="sd1_interface_fig_AutoCloseablePromise-2-co"/> PrintStream out;
...
  public void println(final String s){
    out.println(s); }

  public void close() <co linkends="sd1_interface_fig_AutoCloseablePromise-3"
              xml:id="sd1_interface_fig_AutoCloseablePromise-3-co"/>{
    out.close(); <co linkends="sd1_interface_fig_AutoCloseablePromise-4"
              xml:id="sd1_interface_fig_AutoCloseablePromise-4-co"/>
    out = null; <co linkends="sd1_interface_fig_AutoCloseablePromise-5"
              xml:id="sd1_interface_fig_AutoCloseablePromise-5-co"/>
  }
}</programlisting></td>
      </tr>
    </informaltable>

    <informaltable border="0" role="slideExclude">
      <tr>
        <td valign="top"><calloutlist>
            <callout arearefs="sd1_interface_fig_AutoCloseablePromise-1.2-co"
                     xml:id="sd1_interface_fig_AutoCloseablePromise-1.2">
              <para><xref linkend="glo_Java"/> standard package.</para>
            </callout>

            <callout arearefs="sd1_interface_fig_AutoCloseablePromise-2.2-co"
                     xml:id="sd1_interface_fig_AutoCloseablePromise-2.2">
              <para>Method declaration without implementing body.</para>
            </callout>
          </calloutlist></td>

        <td valign="top"><calloutlist>
            <callout arearefs="sd1_interface_fig_AutoCloseablePromise-1-co"
                     xml:id="sd1_interface_fig_AutoCloseablePromise-1">
              <para>Promise to implement the <classname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/AutoCloseable.html">AutoCloseable</classname>
              interface. This boils down to implement <methodname>public void
              close()</methodname> at <coref
              linkend="sd1_interface_fig_AutoCloseablePromise-3-co"/>.</para>

              <para>Notice the <classname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Override.html">@Override</classname>
              annotation resemblance to overriding base class methods in
              derived classes.</para>
            </callout>

            <callout arearefs="sd1_interface_fig_AutoCloseablePromise-2-co"
                     xml:id="sd1_interface_fig_AutoCloseablePromise-2">
              <para><code language="java">final</code> has been removed in
              favour of setting <code language="java">out</code> to <code
              language="java">null</code> at <coref
              linkend="sd1_interface_fig_AutoCloseablePromise-5-co"/>.</para>
            </callout>

            <callout arearefs="sd1_interface_fig_AutoCloseablePromise-3-co"
                     xml:id="sd1_interface_fig_AutoCloseablePromise-3">
              <para>Renaming former <methodname>closeFile()</methodname>
              method to <methodname>close()</methodname> keeping the interface
              promise made at <coref
              linkend="sd1_interface_fig_AutoCloseablePromise-1-co"/>.</para>

              <para>Caution: No <classname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Override.html">@Override</classname>
              here since close() is being implemented rather tan overriding a
              base class method not existing anyway.</para>
            </callout>

            <callout arearefs="sd1_interface_fig_AutoCloseablePromise-4-co"
                     xml:id="sd1_interface_fig_AutoCloseablePromise-4">
              <para>Closing the <classname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/io/PrintStream.html">PrintStream</classname>
              thereby flushing buffered strings prior to releasing allocated
              operating system resources.</para>
            </callout>

            <callout arearefs="sd1_interface_fig_AutoCloseablePromise-5-co"
                     xml:id="sd1_interface_fig_AutoCloseablePromise-5">
              <para>Setting <code language="java">out</code> to <code
              language="java">null</code> causes subsequent
              <classname>Text2File</classname>.<methodname>println(...)</methodname>
              calls throwing a <classname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/NullPointerException.html">NullPointerException</classname>.
              Thus silent errors become observable errors.</para>
            </callout>
          </calloutlist></td>
      </tr>
    </informaltable>
  </figure>

  <figure xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass">
    <title><code language="java">abstract</code> class replacement</title>

    <informaltable border="0">
      <tr>
        <td valign="top"><programlisting language="java">package hdm.project; <co
              linkends="sd1_interface_fig_AutoCloseableAsAbstractClass-1"
              xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-1-co"/>

abstract public
    class AutoCloseable <co
              linkends="sd1_interface_fig_AutoCloseableAsAbstractClass-2"
              xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-2-co"/>{

/**
 * Closes this resource,
 * relinquishing any
 * underlying resources.
 */
abstract void close​();<co
              linkends="sd1_interface_fig_AutoCloseableAsAbstractClass-3"
              xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-3-co"/>

}</programlisting></td>

        <td valign="top"><programlisting language="java">public class Text2File
  extends AutoCloseable <co
              linkends="sd1_interface_fig_AutoCloseableAsAbstractClass-4"
              xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-4-co"/>{

  private  PrintStream out;
...
  public void println(final String s){
    out.println(s); }

  @Override public void close() <co
              linkends="sd1_interface_fig_AutoCloseableAsAbstractClass-5"
              xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-5-co"/>{
    out.close();
    out = null;
  }
}</programlisting></td>
      </tr>
    </informaltable>

    <informaltable border="0" role="slideExclude">
      <tr>
        <td valign="top"><calloutlist>
            <callout arearefs="sd1_interface_fig_AutoCloseableAsAbstractClass-1-co"
                     xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-1">
              <para><quote>Private</quote> project package.</para>
            </callout>

            <callout arearefs="sd1_interface_fig_AutoCloseableAsAbstractClass-2-co"
                     xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-2">
              <para>Replacing <code language="java">interface</code> by <code
              language="java">abstract</code> class.</para>
            </callout>

            <callout arearefs="sd1_interface_fig_AutoCloseableAsAbstractClass-3-co"
                     xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-3">
              <para>abstract <methodname>close()</methodname> not providing an
              implementing body.</para>
            </callout>
          </calloutlist></td>

        <td valign="top"><calloutlist>
            <callout arearefs="sd1_interface_fig_AutoCloseableAsAbstractClass-4-co"
                     xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-4">
              <para>Extending <code language="java">abstract</code> class
              <classname>AutoCloseable</classname> replaces implementing the
              <classname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/AutoCloseable.html">AutoCloseable</classname>
              interface.</para>
            </callout>

            <callout arearefs="sd1_interface_fig_AutoCloseableAsAbstractClass-5-co"
                     xml:id="sd1_interface_fig_AutoCloseableAsAbstractClass-5">
              <para>Overriding (and in fact implementing) the abstract base
              class <methodname>close()</methodname> method.</para>
            </callout>
          </calloutlist></td>
      </tr>
    </informaltable>
  </figure>

  <figure xml:id="sd1_interface_fig_whyInterfacesVsAbstractClasses">
    <title><code language="java">interface</code> vs. <code
    language="java">abstract</code> class</title>

    <itemizedlist>
      <listitem>
        <para><xref linkend="glo_Java"/> disallows multiple
        inheritance.</para>
      </listitem>

      <listitem>
        <para>A class may implement an arbitrary number of interfaces:</para>

        <programlisting language="java">public class X implements I1, I2, I3 {...}</programlisting>
      </listitem>
    </itemizedlist>
  </figure>

  <figure xml:id="sd1_interface_fig_interfaceMyAutoCloseable">
    <title><code language="java">interface</code>
    <classname>MyAutoCloseable</classname></title>

    <programlisting language="java">/**
 * Support auto-closing of resources
 */
public interface MyAutoCloseable {
  /**
   * close resource in question. Example: Terminate
   * a database connection or a file stream.
   */
  public void close();
}</programlisting>
  </figure>

  <figure xml:id="sd1_interface_fig_extendMyAutoCloseable">
    <title>Extending <classname>MyAutoCloseable</classname> to flush</title>

    <programlisting language="java">/**
 * Flush pending values.
 */
public interface MyFlushable extends MyAutoCloseable {

  /**
   * Save pending i.e. buffered values.
   */
  public void flush();
}</programlisting>
  </figure>

  <figure xml:id="sd1_interface_fig_useFlushable">
    <title>Using <classname>MyFlushable</classname></title>

    <programlisting language="none">public class Text2FileFlushable implements MyFlushable {
  private PrintStream out;
...
  <emphasis role="red">/**
   * Flushing pending output to underlying file.
   */
  public void flush(){
    out.flush();
  }</emphasis>
  /**
   * Closing file thereby flushing buffer. Caution: Further calls
   * to {@link #println(String)} will fail!.
   */
  public void close() {
    out.close();
    out = null;
  }
}</programlisting>
  </figure>

  <figure xml:id="sd1_interface_fig_MyFlushHierarchy">
    <title>Inheritance hierarchy</title>

    <mediaobject>
      <imageobject>
        <imagedata fileref="Ref/Interfaces/flushable.multi.svg"/>
      </imageobject>
    </mediaobject>
  </figure>

  <figure xml:id="sd1_interface_fig_upcomingTopics">
    <title>Upcoming topics</title>

    <itemizedlist>
      <listitem>
        <para>Default methods.</para>
      </listitem>

      <listitem>
        <para>Base classes.</para>
      </listitem>
    </itemizedlist>
  </figure>

  <section xml:id="sw1SectInterfacesSorting">
    <title>Interfaces and sorting</title>

    <figure xml:id="sd1_fig_StringInterfaces">
      <title>Interfaces implemented by class <classname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</classname></title>

      <mediaobject>
        <imageobject>
          <imagedata fileref="Ref/Interfaces/stringComparable.multi.svg"/>
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sd1_fig_InterfaceComparable">
      <title>The <classname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable</classname>
      interface</title>

      <programlisting language="java">interface <link
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable</link>&lt;<emphasis
          role="red">T</emphasis>&gt; {
<emphasis role="red">                ┌────┘</emphasis>  
                <emphasis role="red">▼</emphasis>
  int <link
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html#compareTo(T)">compareTo​</link>(<emphasis
          role="red">T</emphasis> o);

}</programlisting>
    </figure>

    <figure xml:id="sd1_fig_StringComparable">
      <title>class <classname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</classname>
      and <classname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable</classname></title>

      <programlisting language="none">public class <link
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</link> implements <link
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable</link> &lt;<emphasis
          role="red">String</emphasis> <co
          linkends="sd1_callout_StringComparable-1"
          xml:id="sd1_callout_StringComparable-1-co"/>&gt;, ... {
  ...                           <emphasis role="red">┌────────────┘</emphasis>          
  @Override                     <emphasis role="red">▼</emphasis>
  public int <link
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html#compareTo(java.lang.String)">compareTo</link>(final <emphasis
          role="red">String</emphasis> <co
          linkends="sd1_callout_StringComparable-2"
          xml:id="sd1_callout_StringComparable-2-co"/> other) {
     ...
    return ...;
  }
}</programlisting>

      <calloutlist role="slideExclude">
        <callout arearefs="sd1_callout_StringComparable-1-co"
                 xml:id="sd1_callout_StringComparable-1">
          <para>Type parameter <classname
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</classname>
          to interface <classname
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable</classname>.</para>
        </callout>

        <callout arearefs="sd1_callout_StringComparable-2-co"
                 xml:id="sd1_callout_StringComparable-2">
          <para>Matching type <classname
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</classname>
          to type parameter in <coref
          linkend="sd1_callout_StringComparable-1-co"/>.</para>
        </callout>
      </calloutlist>
    </figure>

    <figure xml:id="sd1_fig_StringCompareExamples">
      <title>Comparison examples</title>

      <informaltable border="0">
        <colgroup width="56%"/>

        <colgroup width="44%"/>

        <tr>
          <td valign="top"><programlisting language="java">System.out.println("Eve".compareTo("Paul"));      <co
                linkends="sd1_callout_stringCompareExamples-1"
                xml:id="sd1_callout_stringCompareExamples-1-co"/>
System.out.println("Victor".compareTo("Andrew")); <co
                linkends="sd1_callout_stringCompareExamples-2"
                xml:id="sd1_callout_stringCompareExamples-2-co"/>
System.out.println("Hannah".compareTo("Hannah")); <co
                linkends="sd1_callout_stringCompareExamples-3"
                xml:id="sd1_callout_stringCompareExamples-3-co"/></programlisting></td>

          <td valign="top"><screen>-11 <coref
                linkend="sd1_callout_stringCompareExamples-1-co"/>
21  <coref linkend="sd1_callout_stringCompareExamples-2-co"/>
0   <coref linkend="sd1_callout_stringCompareExamples-3-co"/></screen></td>
        </tr>
      </informaltable>

      <calloutlist role="slideExclude">
        <callout arearefs="sd1_callout_stringCompareExamples-1-co"
                 xml:id="sd1_callout_stringCompareExamples-1">
          <para><code language="java">"Eve"</code> is lexicographically
          smaller than <code language="java">"Paul"</code>.</para>
        </callout>

        <callout arearefs="sd1_callout_stringCompareExamples-2-co"
                 xml:id="sd1_callout_stringCompareExamples-2">
          <para><code language="java">"Victor"</code> is lexicographically
          greater than <code language="java">"Andrew"</code>.</para>
        </callout>

        <callout arearefs="sd1_callout_stringCompareExamples-3-co"
                 xml:id="sd1_callout_stringCompareExamples-3">
          <para><code language="java">"Hannah"</code> is (lexicographically)
          equal to <code language="java">"Hannah"</code>.</para>
        </callout>
      </calloutlist>
    </figure>

    <figure xml:id="sd1_fig_StringSortAscDesc">
      <title>Ascending and descending names</title>

      <mediaobject>
        <imageobject>
          <imagedata fileref="Ref/Interfaces/stringAscDesc.multi.svg"/>
        </imageobject>
      </mediaobject>
    </figure>

    <figure xml:id="sd1_fig_ApiRequirements">
      <title>API requirements</title>

      <orderedlist>
        <listitem>
          <para>Antisymmetric: sgn(x.compareTo(y)) ==
          -sgn(y.compareTo(x))</para>
        </listitem>

        <listitem>
          <para>Transitive: <code language="java">x.compareTo(y)</code> &gt; 0
          and <code language="java">y.compareTo(z) &gt; 0</code> ⇒ <code
          language="java">x.compareTo(z) &gt; 0</code>.</para>
        </listitem>

        <listitem>
          <para><code language="java">x.compareTo(y)==0</code> ⇒ that <code
          language="java">sgn(x.compareTo(z)) == sgn(y.compareTo(z))</code>,
          for all z.</para>
        </listitem>

        <listitem>
          <para>Recommendation: <code language="java">(x.compareTo(y)==0) ==
          (x.equals(y))</code></para>
        </listitem>
      </orderedlist>
    </figure>

    <figure xml:id="sd1_fig_StringSortAscending">
      <title>Sorting strings alphabetically</title>

      <informaltable border="0">
        <colgroup width="72%"/>

        <colgroup width="28%"/>

        <tr>
          <td valign="top"><programlisting language="java">final <link
                xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</link>[] names = { <co
                linkends="sd1_callout_StringSortAscending-1"
                xml:id="sd1_callout_StringSortAscending-1-co"/>
  "Laura", "Aaron", "Tim", "Peter", "Eve", "Bernie"
};

Arrays.<link xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(java.lang.Object%5B%5D)">sort</link>(names); <co
                linkends="sd1_callout_StringSortAscending-2"
                xml:id="sd1_callout_StringSortAscending-2-co"/>
for (final String n: names) { <co linkends="sd1_callout_StringSortAscending-3"
                xml:id="sd1_callout_StringSortAscending-3-co"/>
  System.out.println(n);
}</programlisting></td>

          <td valign="top"><screen>Aaron
Bernie
Eve
Laura
Peter
Tim</screen></td>
        </tr>
      </informaltable>

      <calloutlist role="slideExclude">
        <callout arearefs="sd1_callout_StringSortAscending-1-co"
                 xml:id="sd1_callout_StringSortAscending-1">
          <para>An array of names in random lexicographical order.</para>
        </callout>

        <callout arearefs="sd1_callout_StringSortAscending-2-co"
                 xml:id="sd1_callout_StringSortAscending-2">
          <para><methodname
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(java.lang.Object%5B%5D)">Arrays.sort</methodname>(Object[]
          a) will rearrange the array of names alphabetically in ascending
          order as being defined by <methodname
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html#compareTo(java.lang.String)">String.compareTo</methodname>(String
          anotherString), see left part of <xref
          linkend="sd1_fig_StringSortAscDesc"/>.</para>
        </callout>

        <callout arearefs="sd1_callout_StringSortAscending-3-co"
                 xml:id="sd1_callout_StringSortAscending-3">
          <para>The sorted array's content is being written to standard
          output.</para>
        </callout>
      </calloutlist>
    </figure>

    <qandaset defaultlabel="qanda" xml:id="sd1QandaArraysSortUnderstand">
      <title>Understanding <methodname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(java.lang.Object%5B%5D)">Arrays.sort()</methodname></title>

      <qandadiv>
        <qandaentry>
          <question>
            <para>Consider a simple <classname>Rectangle</classname>
            class:</para>

            <programlisting language="java">public class Rectangle {

    public final int width, height;

    public Rectangle(final int width, final int height) {
        this.width = width;
        this.height = height;
    }
    @Override public String toString() {
        return width + " x " + height;
    }
}</programlisting>

            <para>We would like to be able sorting
            <classname>Rectangle</classname> instances by their respective
            width using <methodname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(java.lang.Object%5B%5D)">Arrays.sort(Object[]
            a)</methodname>. Right now sorting does not work at all.
            Consider:</para>

            <programlisting language="java">final Rectangle[] rectangles = new Rectangle[]{
  new Rectangle(2, 3),
  new Rectangle(4, 5),
  new Rectangle(4, 1)};

 Arrays.sort(rectangles);</programlisting>

            <para>This code compiles well. Execution however fails:</para>

            <screen>Exception in thread "main" java.lang.ClassCastException: de.hdm_stuttgart.mi.sd1.model.Rectangle
  cannot be cast to java.base/java.lang.Comparable
	at java.base/java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
	at java.base/java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
	at java.base/java.util.Arrays.sort(Arrays.java:1248)
	at de.hdm_stuttgart.mi.sd1.App.test1(App.java:28)
	at de.hdm_stuttgart.mi.sd1.App.main(App.java:19)</screen>

            <para>Why does this happen? Read <methodname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(java.lang.Object%5B%5D)">Arrays.sort(Object[]
            a)</methodname>'s documentation and try to understand the <link
            xlink:href="http://hg.openjdk.java.net/jdk/jdk/file/300523d8b7b3/src/java.base/share/classes/java/util/ComparableTimSort.java">ComparableTimSort.java
            line 320 implementation</link> causing the above <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/ClassCastException.html">ClassCastException</classname>.
            You don't have to understand what exactly the code does. Instead
            focus on types being involved.</para>
          </question>

          <answer>
            <para>Our <code language="java">Rectangle[]</code> array is being
            passed as <code language="java">Object[]</code> in <code
            language="java">Arrays.sort(rectangles)</code>. Inside <classname
            xlink:href="http://hg.openjdk.java.net/jdk/jdk/file/300523d8b7b3/src/java.base/share/classes/java/util/ComparableTimSort.java">ComparableTimSort</classname>
            we have:</para>

            <programlisting language="java">private static int countRunAndMakeAscending(Object[] a, int lo, int hi) {
  ... 
if ((<emphasis role="red">(Comparable) a[...]</emphasis>).compareTo(...) &lt; 0) { </programlisting>

            <para>This is an attempt casting an <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html">Object</classname>
            to <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable</classname>.
            Since our <classname>Rectangle</classname> class does not yet
            implement the <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable</classname>
            interface this cast is bound to fail.</para>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>

    <qandaset defaultlabel="qanda" xml:id="sd1QandaArraysSortByWidth">
      <title>Sorting <classname>Rectangle</classname> instances by
      width</title>

      <qandadiv>
        <qandaentry>
          <question>
            <para>Correct <xref linkend="sd1QandaArraysSortUnderstand"/> by
            implementing the <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable</classname>
            interface in <classname>Rectangle</classname>. More precisely use
            the underlying type parameter <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html">Comparable&lt;Rectangle&gt;</classname>.
            Thus is an anticipation of upcoming <xref linkend="glo_Java"/>
            <link
            xlink:href="https://docs.oracle.com/javase/tutorial/java/generics">generics</link>.</para>
          </question>

          <answer>
            <para>We implement the interface consisting only of one method
            <methodname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html#compareTo(T)">compareTo(T
            o)</methodname> with <code language="java">T</code> representing
            the type in question:</para>

            <programlisting language="java">public class Rectangle implements Comparable&lt;Rectangle&gt; {
...
  @Override
  public String toString() {
    return width + " x " + height;
  }
  @Override
  public int compareTo(final Rectangle other) {
    return  width - other.width;
  }
}</programlisting>

            <para>This solves the <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/ClassCastException.html">ClassCastException</classname>
            runtime problem and sorts <classname>Rectangle</classname>
            instances by width:</para>

            <informaltable border="0">
              <tr>
                <td valign="top"><programlisting language="java">final Rectangle[] rectangles = new Rectangle[]{
  new Rectangle(2, 3),
  new Rectangle(4, 5),
  new Rectangle(4, 1)};

Arrays.sort(rectangles);

for (final Rectangle n : rectangles) {
  System.out.println(n);
}</programlisting></td>

                <td valign="top"><screen>2 x 3
4 x 5
4 x 1</screen></td>
              </tr>
            </informaltable>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>

    <qandaset defaultlabel="qanda" xml:id="sd1QandaArraysSortByWidthAndHeight">
      <title>Sorting <classname>Rectangle</classname> instances by width and
      height</title>

      <qandadiv>
        <qandaentry>
          <question>
            <para>Our current sorting implementation may be considered
            incomplete. We may have multiple <classname>Rectangle</classname>
            instances of common width but differing in height as in the
            current example:</para>

            <informaltable border="0">
              <tr>
                <td valign="top"><programlisting language="java">final Rectangle[] rectangles = new Rectangle[]{
  new Rectangle(2, 3),
  new Rectangle(4, 5),
  new Rectangle(4, 1)};</programlisting></td>

                <td valign="top"><screen>2 x 3
<emphasis role="red">4 x 5</emphasis>
<emphasis role="red">4 x 1</emphasis></screen></td>
              </tr>
            </informaltable>
            <para>Two <classname>Rectangle</classname> instances share a
            common width of 4 but differ in height. The original sequence is
            being retained showing the rectangle having larger height 5
            first.</para>

            <para>We want rectangles of common width to be sorted by height in
            ascending order as well. Modify your
            <methodname>compareTo()</methodname> implementation accordingly to
            produce:</para>

            <informaltable border="0">
              <tr>
                <td valign="top"><programlisting language="java">final Rectangle[] rectangles = new Rectangle[]{
  new Rectangle(2, 3),
  new Rectangle(4, 5),
  new Rectangle(4, 1)};</programlisting></td>

                <td valign="top"><screen>2 x 3
<emphasis role="red">4 x 1</emphasis>
<emphasis role="red">4 x 5</emphasis></screen></td>
              </tr>
            </informaltable>
          </question>

          <answer>
            <para>We extend our <methodname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/Comparable.html#compareTo(T)">compareTo(T
            o)</methodname> implementation accounting in case of common width
            values:</para>

            <programlisting language="java">@Override
 public int compareTo(final Rectangle other) {
  if (width == other.width) {
    return height - other.height;
  } else {
    return width - other.width;
  }
}</programlisting>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>

    <figure xml:id="sd1_fig_StringFlexibleSorting">
      <title>Situation dependent sorting criteria</title>

      <informaltable border="0">
        <colgroup width="25%"/>

        <colgroup width="25%"/>

        <colgroup width="25%"/>

        <colgroup width="25%"/>

        <tr>
          <th>Unsorted</th>

          <th>Case sensitive</th>

          <th>Case insensitive</th>

          <th>Descending</th>
        </tr>

        <tr>
          <td valign="top"><screen>UK
quick
hello
sign
ATM</screen></td>

          <td valign="top"><screen>ATM
UK
hello
quick
sign</screen></td>

          <td valign="top"><screen>ATM
hello
quick
sign
UK</screen></td>

          <td valign="top"><screen>sign
quick
hello
UK
ATM</screen></td>
        </tr>
      </informaltable>
    </figure>

    <figure xml:id="sd1_fig_StringFlexibleImplement">
      <title>Implementing flexible sorting</title>

      <para>Solution: Provide your own <classname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Comparator</classname>!</para>

      <programlisting language="none">import java.util.Comparator;

public class SortCaseInsensitive implements <link
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Comparator</link>&lt;<emphasis
          role="red">String</emphasis>&gt; {
                              <emphasis role="red">┏━━━━━━━━━━━━━━┳━━━━━━━━━━━┛</emphasis>
  @Override                   <emphasis role="red">▼              ▼</emphasis>
  public int compare(final <emphasis role="red">String</emphasis> a, final <emphasis
          role="red">String</emphasis> b) {
    return <emphasis role="red">a.toLowerCase()</emphasis>.compareTo(<emphasis
          role="red">b.toLowerCase()</emphasis>);
  }
}</programlisting>
    </figure>

    <figure xml:id="sd1_fig_StringComparatorDemo">
      <title><classname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Comparator</classname>
      in action</title>

      <informaltable border="0">
        <colgroup width="72%"/>

        <colgroup width="28%"/>

        <tr>
          <td valign="top"><programlisting language="none">System.out.println("hello".compareTo("UK")); <co
                linkends="sd1_callout_StringComparatorDemo-1"
                xml:id="sd1_callout_StringComparatorDemo-1-co"/>

System.out.println(new SortCaseInsensitive(). <co
                linkends="sd1_callout_StringComparatorDemo-2"
                xml:id="sd1_callout_StringComparatorDemo-2-co"/>
   compare("hello", "UK"));</programlisting></td>

          <td valign="top"><screen>19 <coref
                linkend="sd1_callout_StringComparatorDemo-1-co"/>
-13 <coref linkend="sd1_callout_StringComparatorDemo-2-co"/></screen></td>
        </tr>
      </informaltable>
      <calloutlist role="slideExclude">
        <callout arearefs="sd1_callout_StringComparatorDemo-1-co"
                 xml:id="sd1_callout_StringComparatorDemo-1">
          <para>Standard <classname
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</classname>
          comparison.</para>
        </callout>

        <callout arearefs="sd1_callout_StringComparatorDemo-2-co"
                 xml:id="sd1_callout_StringComparatorDemo-2">
          <para>Custom <classname
          xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Comparator</classname>
          evaluating <code language="java">"hello".compareTo(<emphasis
          role="red">"uk"</emphasis>)</code> behind the scenes.</para>
        </callout>
      </calloutlist>
    </figure>

    <figure xml:id="sd1_fig_StringSortIgnoreCase">
      <title><classname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Case
      insensitive sort</classname></title>

      <informaltable border="0">
        <colgroup width="72%"/>

        <colgroup width="28%"/>

        <tr>
          <td valign="top"><programlisting language="none">final <link
                xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</link>[] names = {
"UK", "quick", "hello", "sign", "ATM"
};

Arrays.<link xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(T%5B%5D,java.util.Comparator)">sort</link>(names, <emphasis
                role="red">new SortCaseInsensitive()</emphasis>);

for (final String n: names) { 
  System.out.println(n);
}</programlisting></td>

          <td valign="top"><screen>ATM
hello
quick
sign
UK</screen></td>
        </tr>
      </informaltable>
    </figure>

    <figure xml:id="sd1_fig_StringSortIgnoreCaseLambda">
      <title><classname
      xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Sort
      descending by lambda expression</classname></title>

      <informaltable border="0">
        <colgroup width="72%"/>

        <colgroup width="28%"/>

        <tr>
          <td valign="top"><programlisting language="none">final <link
                xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</link>[] names = {
"UK", "quick", "hello", "sign", "ATM"
};
Arrays.<link xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(T%5B%5D,java.util.Comparator)">sort</link>(names, <emphasis
                role="red">(a, b) -&gt; b.compareTo(a)</emphasis>); <co
                linkends="sd1_callout_StringSortIgnoreCaseLambda-1"
                xml:id="sd1_callout_StringSortIgnoreCaseLambda-1-co"/>
for (final String n: names) { 
  System.out.println(n);
}</programlisting></td>

          <td valign="top"><screen>sign
quick
hello
UK
ATM</screen></td>
        </tr>
      </informaltable>

      <calloutlist role="slideExclude">
        <callout arearefs="sd1_callout_StringSortIgnoreCaseLambda-1-co"
                 xml:id="sd1_callout_StringSortIgnoreCaseLambda-1">
          <para>This lambda expression is equivalent to the following custom
          comparator:</para>

          <programlisting language="none">public class SortDescending implements <link
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Comparator</link>&lt;String&gt; {
    @Override
    public int compare(final String <emphasis role="red">a</emphasis>, final String <emphasis
              role="red">b</emphasis>) {
        return <emphasis role="red">b.compareTo(a)</emphasis>; // Equivalent to <coref
              linkend="sd1_callout_StringSortIgnoreCaseLambda-1-co"/>
    }
}</programlisting>
        </callout>
      </calloutlist>
    </figure>

    <qandaset defaultlabel="qanda" xml:id="sd1QandaArraysFlexibleSorting">
      <title>Adding flexibility in sorting rectangles</title>

      <qandadiv>
        <qandaentry>
          <question>
            <para>We want to change the ordering of rectangles in a flexible
            manner. Consider the following examples:</para>

            <itemizedlist>
              <listitem>
                <para>A list of rectangles may be ordered either by width,
                area or perimeter.</para>
              </listitem>

              <listitem>
                <para>The ordering may be ascending or descending</para>
              </listitem>
            </itemizedlist>

            <para>Define an additional ordering prescription: Rectangle
            instances shall be sortable by area in descending order in
            addition to the already defined ordering by width and height.
            Instances sharing common area shall be sorted first by width and
            second by height in descending order as well.</para>

            <tip>
              <para>The <methodname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(T%5B%5D,java.util.Comparator)">sort(T[]
              a, Comparator&lt;? super T&gt; c)</methodname> method is your
              friend. It allows for passing a comparator instance as in the
              <link
              xlink:href="https://www.geeksforgeeks.org/arrays-sort-in-java-with-examples/#highlighter_983402">sort
              students by rollno</link> example. Thus define an appropriate
              SortByArea class implementing <classname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Comparator&lt;Rectangle&gt;</classname>
              and pass an instance of this class to <methodname
              xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#sort(T%5B%5D,java.util.Comparator)">sort(T[]
              a, Comparator&lt;? super T&gt; c)</methodname>.</para>
            </tip>
          </question>

          <answer>
            <para>For convenience we add a <methodname>getArea()</methodname>
            method to our <classname>Rectangle</classname> class:</para>

            <programlisting language="java">public class Rectangle implements Comparable&lt;Rectangle&gt; {
   ...
  public int getArea() {
    return width * height;
  }
}</programlisting>

            <para>The intended sorting requires a corresponding class
            implementing the <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Comparator</classname>
            (Not <classname>Comparable</classname>!) interface:</para>

            <programlisting language="java">public class SortByArea implements <classname
                xlink:href="https://docs.oracle.com/javase/10/docs/api/java/util/Comparator.html">Comparator</classname>&lt;Rectangle&gt; {
  @Override
  public int compare(Rectangle r1, Rectangle r2) {
    if (r1.width * r1.height == r2.width * r2.height) {
      if (r1.width == r2.width) {
        return r2.height - r1.height; <co
                linkends="sd1_listing_sortRectangleByArea-1"
                xml:id="sd1_listing_sortRectangleByArea-1-co"/>
      } else {
        return r2.width - r1.width; <co
                linkends="sd1_listing_sortRectangleByArea-2"
                xml:id="sd1_listing_sortRectangleByArea-2-co"/>
      }
    } else {
      return r2.width * r2.height - r1.width * r1.height; <co
                linkends="sd1_listing_sortRectangleByArea-3"
                xml:id="sd1_listing_sortRectangleByArea-3-co"/>
    }
  }
}</programlisting>

            <calloutlist>
              <callout arearefs="sd1_listing_sortRectangleByArea-1-co"
                       xml:id="sd1_listing_sortRectangleByArea-1">
                <para>Two rectangles having common area and width
                values.</para>
              </callout>

              <callout arearefs="sd1_listing_sortRectangleByArea-2-co"
                       xml:id="sd1_listing_sortRectangleByArea-2">
                <para>Two rectangles having common area values but different
                width.</para>
              </callout>

              <callout arearefs="sd1_listing_sortRectangleByArea-3-co"
                       xml:id="sd1_listing_sortRectangleByArea-3">
                <para>Two rectangles having different area values.</para>
              </callout>
            </calloutlist>

            <para>We may now use both ordering prescriptions next to each
            other:</para>

            <informaltable border="0">
              <tr>
                <td valign="top"><programlisting language="java">final Rectangle[] rectangles = new Rectangle[]{
  new Rectangle(2, 3),
  new Rectangle(3, 2),
  new Rectangle(4, 5),
  new Rectangle(4, 1)};

System.out.println("Ascending by width and height:");
Arrays.sort(rectangles);
for (final Rectangle r : rectangles) {
  System.out.println(r);
}

System.out.println("\nDescending by area, width and height:");
Arrays.sort(rectangles, new SortByArea());
for (final Rectangle r : rectangles) {
  System.out.println(r + ", area = " + r.getArea());
}</programlisting></td>

                <td valign="top"><screen>Ascending by width and height:
2 x 3
3 x 2
4 x 1
4 x 5

Descending by area, width and height:
4 x 5, area = 20
<emphasis role="red">3 x 2, area = 6</emphasis>
<emphasis role="red">2 x 3, area = 6</emphasis>
4 x 1, area = 4</screen><para>Notice the two rectangles having a common area
                value of 6 being sorted by descending width value.</para></td>
              </tr>
            </informaltable>

            <para>Side note: Upcoming lambda expressions in Software
            development 2 allow for defining sorting methods directly without
            requiring classes. We provide two simple examples:</para>

            <informaltable border="0">
              <tr>
                <td valign="top"><programlisting language="java">final Rectangle[] rectangles = new Rectangle[]{
  new Rectangle(2, 3),
  new Rectangle(3, 2),
  new Rectangle(4, 5),
  new Rectangle(4, 1)};

System.out.println("Descending by width:");
Arrays.sort(rectangles, <emphasis role="red">(x, y) -&gt; y.width - x.width</emphasis>);
for (final Rectangle r : rectangles) {
  System.out.println(r);
}

System.out.println("\nAscending by area:");
Arrays.sort(rectangles, <emphasis role="red">(x, y) -&gt; x.getArea() - y.getArea()</emphasis>);
for (final Rectangle r : rectangles) {
  System.out.println(r + ", area = " + r.getArea());
}</programlisting></td>

                <td valign="top"><screen>Descending by width:
4 x 5
4 x 1
3 x 2
2 x 3

Ascending by area:
4 x 1, area = 4
3 x 2, area = 6
2 x 3, area = 6
4 x 5, area = 20</screen></td>
              </tr>
            </informaltable>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>
  </section>

  <section xml:id="sw1SectNonsenseGenerator">
    <title>A nonsense generator</title>

    <qandaset defaultlabel="qanda" xml:id="sd1QandaNonsenseGenerator">
      <qandadiv>
        <qandaentry>
          <question>
            <para>Consider the following <classname
            xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/String.html">String</classname>
            array definitions:</para>

            <programlisting language="java">private static final String[] ADJECTIVES = {
      "red",       "green",    "yellow",     "gray",        "solid",   // Index 4
      "fierce",    "friendly", "cowardly",   "convenient",  "foreign", // Index 9
      "national",  "tall",     "short",      "metallic",    "golden",  // Index 14
      "silver",    "sweet",    "nationwide", "competitive", "stable",  // Index 19
      "municipal", "famous" };                                         // Index 21

private static final String[] THINGS = {
      "elephant",   "bowl",    "brick",  "spoon",   "bunny",    // Index 4
      "watermelon", "car",     "cat",    "cup",     "desk",     // Index 9
      "tangerine",  "duck",    "bottle", "road" ,   "fork",     // Index 14
      "physicist",  "griffon", "hat",    "key",     "knife",    // Index 19
      "lawyer",     "llama",   "manual", "meat",    "monitor",  // Index 24
      "mouse",      "dog",     "paper",  "pear",    "pen",      // Index 28
      "pencil",     "phone",   "glass",  "planet",  "potato",   // Index 34
      "engineer",   "salad",   "shoe",   "slipper", "soup",     // Index 39
      "building",   "star",    "steak",  "table",   "terminal", // Index 44
      "treehouse",  "truck",   "cake",   "window" };            // Index 48

private static final String[] VERBS = {
"plans cease fire against", "expected to sell","expected to buy","speaks to","leases",   // Index 4
"signs partnership with",   "advances towards","meets with",     "seen with","sells",    // Index 9
"is authorized to sell",    "signs truce with","converts into",  "buys",     "rents",    // Index 14
"allegedly speaks to",      "collapses on",    "invests on",     "warns",    "threatens",// Index 19
"reported to have met with","now manages",     "starts war with","accuses",  "becomes" , // Index 24
"works together with" };                                                                 // Index 25
</programlisting>

            <para>Following the build principle <quote><code>The {adjective}
            {thing} {verb} a {thing}.</code></quote> we may randomly generate
            nonsense phrases like e.g.:</para>

            <screen>The red meat now manages a bunny.
The metallic duck works together with a duck.
The competitive bottle signs truce with a treehouse.
The nationwide potato buys a monitor.</screen>

            <para>Implement an appropriate phrase generator obeying the
            following guidelines:</para>

            <orderedlist>
              <listitem>
                <para>Use a random number generator. Test your implementation
                by a simple <methodname>main()</methodname> method.</para>
              </listitem>

              <listitem>
                <para>Your solution should still work when extending the
                mentioned arrays of verbs, things and adjectives.</para>
              </listitem>

              <listitem>
                <para>Your solution should be testable. But having a random
                number generator in place effectively defies
                testability.</para>

                <para>Define an appropriate interface which allows for
                cheating by replacing a random generator with a
                (deterministic) sequence generator. The latter will then be
                used for unit testing allowing for predictable results.</para>

                <para>Thus you effectively mock a random generator by a
                predictable sequence generator:</para>

                <programlisting language="java">@Test
public void testApp() {
   final NonsenseGenerator nonsenseGenerator = new  NonsenseGenerator(
         new PredictableSequenceGenerator(new int[]{
         //adjective thing verb thing
           3,        7,    19,  26, // First sentence fixed index values
           6,        20,   7,   15  // Second sentence fixed index values
   }));

   Assert.assertEquals("The gray cat threatens a dog.",
         nonsenseGenerator.generateRandomSentence());
   Assert.assertEquals("The friendly lawyer meets with a physicist.",
         nonsenseGenerator.generateRandomSentence());
}</programlisting>
              </listitem>
            </orderedlist>
          </question>

          <answer>
            <annotation role="make">
              <para role="eclipse">Sd1/NonsenseGenerator</para>
            </annotation>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>
  </section>

  <section xml:id="sd1SectPlotterInterface">
    <title>An interface based plotter</title>

    <qandaset defaultlabel="qanda" xml:id="sd1QandaPlotInterface">
      <qandadiv>
        <qandaentry>
          <question>
            <para>In <xref linkend="sd1SectPlottingFunctions"/> you
            implemented a plotter hard coding the desired plot function e.g.
            <function>y = sin(x)</function>.</para>

            <para>A better solution will separate the plotter's implementation
            from the desired plotting function. The idea is defining a
            corresponding interface:</para>

            <programlisting language="java">public interface DoubleOfDouble {
   /**
    * A function expecting a double argument and returning
    * a double value like e.g. double Math.sin(double)
    * @param x An argument
    * @return A value
    */
   public double compute(double x);
}</programlisting>

            <para>This interface may be used by the plotter class as a
            <quote>placeholder</quote> for the intended plot function.
            Plotting e.g. <function>y=sin(x)</function> will then be effected
            by:</para>

            <programlisting language="java">class MySin implements DoubleOfDoubleFunction {

   @Override
   public double compute(double x) {
      return Math.sin(x);
   }
}</programlisting>

            <para>Plotting will then require an instance:</para>

            <programlisting language="java">final DoubleOfDoubleFunction sinFunction = new MySin();
plotter.plot(sinFunction);</programlisting>
          </question>

          <answer>
            <annotation role="make">
              <para role="eclipse">Sd1/plot/Basic</para>

              <para>A <quote>standard</quote> plotting example is being
              provided in class <classname>DriverInterface</classname>.</para>
            </annotation>

            <para>The solution in addition contains a variant
            <classname>DriverLambda</classname> using <link
            xlink:href="http://tutorials.jenkov.com/java/lambda-expressions.html">Java
            8 lambda expressions</link> which allows for supplying functions
            as arguments to the plotting facility. This solution will not be
            covered in the current lecture but you may catch a glimpse with
            respect to upcoming topics in <quote
            xml:lang="de">Softwareentwicklung 2</quote>:</para>

            <programlisting language="java">public class DriverLambda {

    /**
     * @param args Unused
     */
    public static void main( String[] args ) {
        final Plotter plotter = new Plotter();

        plotter.setNumTics(80, 40);// 80 characters vertical, 40 characters horizontal
        plotter.setXrange(0, 2 * Math.PI);
        plotter.setYrange(-1, 1);

        // Function implementing the underlying interface
        // de.hdm_stuttgart.mi.sd1.plot.DoubleOfDoubleFunction
        // are being conveniently passed as arguments.
        plotter.plot(<emphasis role="bold">x -&gt; Math.sin(x)</emphasis>);
        plotter.plot(<emphasis role="bold">x -&gt; Math.cos(x)</emphasis>);
    }
}</programlisting>
          </answer>
        </qandaentry>
      </qandadiv>
    </qandaset>
  </section>
</chapter>