public Solmu(Object uusi) {
      // Hyväksytään, että voidaan rakentaa null-arvoisella alkiolla.
      alkio = uusi;
      seuraava = null;
   }

   /*
    * Aksessorit
    *
    */

   public void alkio(Object uusi) {
      if (uusi != null)
         alkio = uusi;
   }

   public Object alkio() { return alkio; }

   public void seuraava(Solmu s) {
      seuraava = s;
   }

   public Solmu seuraava() { return seuraava; }

   /*
    * Object-luokan korvatut metodit.
    *
    */

   /** Korvataan Object-luokan metodi siten, että kutsutaan alkion metodia.
     * Jos tämä ei ole mahdollista, niin käytetään sittenkin kiltisti
     * Object-luokan metodia.
     */
   public String toString() {
      if (alkio != null)
         return alkio.toString();
      else
         return super.toString();
   }
}

public class Lista {

   /*=============================================================
    *
    * Olioattribuutit
    *
    */

   /** Listan pää. */
   private Solmu paa;

   /** Listan häntä. */
   private Solmu hanta;

   /** Listan alkioiden lukumäärä. */
   private int koko;

   /*=============================================================
    *
    * Rakentajat
    *
    */

   /** Alustetaan paa- ja hanta-attribuutit null-arvoihin ja asetetaan
     * koko-attribuutin arvoksi nolla.
     *
     */
   public Lista() {
     paa = null;
     hanta = null;
     koko = 0;
   }


   /*=============================================================
    *
    * Apumetodeja
    *
    */

   /** Tarkistetaan onko paikka kunnollinen.
     *
     * @param paikka listan indeksi.
     * @return true, jos paikka ok, muuten false.
     */
   private boolean paikkaOK(int paikka) {
      return (0 <= paikka) && (paikka < koko);
   }

   /** Palauttaa annetussa paikassa olevan solmun.
     * Mikäli paikka on virheellinen, paluuarvo on null.
     *
     * @param paikka solmun paikka listassa.
     * @return solmu tai null.
     */
   private Solmu haeSolmu(int paikka) {
      // Paikka kunnollinen.
      if (paikkaOK(paikka)) {

         // Aloitetaan listan päästä.
         Solmu paikanSolmu = paa;

         // Kelataan oikeaan kohtaan.
         for (int i = 0; i < paikka; i++)
            paikanSolmu = paikanSolmu.seuraava();

         // Palautetaan
         return paikanSolmu;
      }

      // Virheellinen paikka.
      else
         return null;
   }

   /*=============================================================
    *
    * Listan operaatiot.
    *
    */

   /** Onko lista tyhjä?
     *
     * @return true, mikäli listassa ei ole solmuja, false muussa tapauksessa.
     */
   public boolean onkoTyhja() {
      return koko == 0;
   }

   /** Lisää uuden solmun linkitetyn listan loppuun.
     *
     * @param alkio lisättävä tieto.
     */
   public void lisaaLoppuun(Object alkio) {

      // Luodaan uusi solmu.
      Solmu uusi = new Solmu(alkio);

      // Tyhjä lista: pää ja häntä ovat sama alkio.
      if (onkoTyhja()) {
         paa = uusi;
         hanta = uusi;
      }
      // Listassa on jo alkioita.
      else {
         // Häntä osoittamaan uuteen alkioon.
         hanta.seuraava(uusi);

         // Uusi alkio hännäksi.
         hanta = uusi;
      }

      // Kasvatetaan listan kokoa yhdellä.
      koko++;
   }

}