Pedro Martins
Pedro Martins

Reputation: 125

For iterator with generic type - Java

I am having trouble with this piece of code. Basically, the main function was given, and it was asked to develop the most simple version of class CountDown, that compiles the code.

Class Main:

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Main {

    public static void main(String[] args) {

        CountDown a = new CountDown(3,15);
        CountDown b = new CountDown(2,20);
        CountDown c = new CountDown(3,15);

        List<CountDown> lst = new ArrayList<CountDown>();
        lst.add(a);
        lst.add(b);
        lst.add(c);

        Set<CountDown> set = new HashSet<CountDown>();
        set.addAll(lst);

        lst.clear();
        lst.addAll(set);
        Collections.sort(lst);

        for(E e : lst) {
            System.out.println(e);
        }

    }

}

Class CountDown:

public class CountDown implements Comparable<CountDown> {
    private int hour;
    private int minute;

    public CountDown(int hour, int minute) throws Exception {

        if ((hour > 23 || hour < 0) && (minute > 59 || minute < 0)) {
            throw new IllegalArgumentException("Horas ou minutos invalidos");
        } else {
            this.hour = hour;
            this.minute = minute;
        }
    }

    public int gethour() {
        return this.hour;
    }

    public int getminute() {
        return this.minute;
    }

    @Override
    public int compareTo(CountDown arg0) {
        int result = 0;
        int minute1 = arg0.getminute();
        int hour1 = arg0.gethour();

        result = this.getminute() - minute1;

        if(result == 0) {
            result = this.gethour() - hour1;
        }

        return result;
    }
}

My problem is that in Main function this piece of code doesn't compile, and I have no idea on how to make it work. Can someone teach me whats wrong?

for(E e : lst) {
    System.out.println(e);
}

Upvotes: 3

Views: 163

Answers (5)

clstrfsck
clstrfsck

Reputation: 14829

To get this to work properly, you probably need a few things.

First up, you will need a trivial interface or class E:

public interface E
{

}

The add the following bits to CountDown. Note comments where things have changed:

// Added "implements E" and provided trivial interface E
// to allow (for E : ...) to work in main(...).
public class CountDown implements E, Comparable<CountDown> {
  private int hour;
  private int minute;

  // Removed unnecessary "throws Exception" specifier
  public CountDown(int hour, int minute) {
    // Previous logic incorrect.  Should throw exception if either hour
    // OR minute is out of range.
    if (hour > 23 || hour < 0 || minute > 59 || minute < 0) {
      throw new IllegalArgumentException("Horas ou minutos invalidos");
    } else {
      this.hour = hour;
      this.minute = minute;
    }
  }

  // Corrected capitalisation to make bean compliant name.
  // Not strictly required.
  public int getHour() {
    return this.hour;
  }

  // Corrected capitalisation to make bean compliant name.
  // Not strictly required.
  public int getMinute() {
    return this.minute;
  }

  @Override
  public int compareTo(CountDown other) {
    // Simplified logic.  Made sort by hours, then by minutes.
    int cmp = Integer.compare(this.getHour(), other.getHour());
    if (cmp == 0)
      cmp = Integer.compare(this.getMinute(), other.getMinute());
    return cmp;
  }

  // Really should have equals(...) method if instances are comparable.
  // Also required if we want to use instances in a HashSet
  @Override
  public boolean equals(Object o)
  {
    if (this == o)
      return true;
    if (o instanceof CountDown)
    {
      CountDown other = (CountDown)o;
      // Ensures that this logic is consistent with compareTo(...)
      return this.compareTo(other) == 0;
    }
    return false;
  }

  // Really should have hashCode() if we have equals.
  // Also required if we want to use instances in a HashSet
  @Override
  public int hashCode()
  {
    // Collision-free hash code given logic in constructor.
    return this.hour * 60 + this.minute;
  }

  // Required to show a sensible value for System.out.print(...) etc
  @Override
  public String toString()
  {
    return String.format("%s[%02d:%02d]", getClass().getSimpleName(),
        this.getHour(), this.getMinute());
  }
}

Given these changes, main(...) should run without modifications.

Upvotes: 3

Samir
Samir

Reputation: 36

It has two errors. 1. CountDown class constructor is marked as "throws exception". When you create an instance of it, it needs to be wrapped it into Try-Catch block. 2. When you iterate the collection of CountDown list, the specified type was wrong in for loop. 3. Fix System.out.println to print user-friendly info.

public class Main {
    public static void main(String[] args) {
        List<CountDown> lst = new ArrayList<CountDown>();
        try
        {
            CountDown a = new CountDown(3,15);
            CountDown b = new CountDown(2,20);
            CountDown c = new CountDown(3,15);
            lst.add(a);
            lst.add(b);
            lst.add(c);
        }
        catch (Exception ex)
        {

        }
        Set<CountDown> set = new HashSet<CountDown>();
        set.addAll(lst);
        lst.clear();
        lst.addAll(set);
        Collections.sort(lst);
        for(CountDown e : lst) {
            System.out.println("Hours: " + e.gethour() + " Minutes: " + e.getminute());
        }

    }
}

Upvotes: 0

so_what
so_what

Reputation: 176

If you need to show the values of the CountDown class,Please override tostring() method as well.. hope it will work...

import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;

    public class Test{

        public static void main(String[] args) throws Exception {
                List<CountDown> lst = new ArrayList<CountDown>();
                CountDown a = new CountDown(3,15);
                CountDown b = new CountDown(2,20);
                CountDown c = new CountDown(3,15);
                lst.add(a);
                lst.add(b);
                lst.add(c);
                Set<CountDown> set = new HashSet<CountDown>();
                set.addAll(lst);
                lst.clear();
                lst.addAll(set);
                Collections.sort(lst);
                for(CountDown e : lst) {
                    System.out.println(e);
                }

        }

    }
     class CountDown implements Comparable<CountDown>{
        private int hour;
        private int minute;

        public CountDown(int hour, int minute) throws Exception {
            if ((hour > 23 || hour < 0) && (minute > 59 || minute < 0)) {
                throw new IllegalArgumentException("Horas ou minutos invalidos");
            } else {
                this.hour = hour;
                this.minute = minute;
            }
        }

        public int gethour() {
            return this.hour;
        }

        public int getminute() {
            return this.minute;
        }

        @Override
        public int compareTo(CountDown arg0) {
            int result = 0;
            int minute1 = arg0.getminute();
            int hour1 = arg0.gethour();
            result = this.getminute() - minute1;
            if(result == 0) {
                result = this.gethour() - hour1;
            }
            return result;
        }
    }

Upvotes: 0

Ousmane D.
Ousmane D.

Reputation: 56423

Two things you'll need to do to remove the compilation errors:

  1. lst contains elements of type CountDown therefore the enhanced for loop variable should be of type CountDown not E i.e. for(CountDown e : lst) { ... }.
  2. Since there is a chance that your constructor could throw an exception you'll either need to declare main as public static void main(String[] args) throws Exception { or wrap the code inside a try/catch.

Upvotes: 1

Pablo Canseco
Pablo Canseco

Reputation: 562

Your lst variable is a list of CountDown objects, so if you change E to CountDown here:

for(E e : lst) {

it should work.

Upvotes: 5

Related Questions