3

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);
}
3
  • 1
    Add a toString() method to your class. Commented Jan 15, 2018 at 22:17
  • 1
    Also, you say "this piece of code doesn't compile" - in that case show us the exact error you get. Commented Jan 15, 2018 at 22:17
  • Multiple markers at this line - Type mismatch: cannot convert from element type CountDown to E - E cannot be resolved to a type Commented Jan 15, 2018 at 22:19

5 Answers 5

5

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

for(E e : lst) {

it should work.

Sign up to request clarification or add additional context in comments.

5 Comments

But the question asks to dont change in Main function
@PedroMartins, I think you were given a main function with a mistake in it. I don't see another way to do it.
Probably... The only thing that was given was the main function, and it says 1) please make the simplest version of countdown that compiles the code
@PabloCanseco, thanks pablo, thats what I was thinking
Ah, I didn't think to make your countdown class implement a E interface. That was a tricky assignment.
3

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.

5 Comments

Could you, if possible, explain the idea behind hashcode? I am not really understanding
hashCode() is used for "bucketing" for data structures that use this approach. There is a wikipedia page (!) here: en.wikipedia.org/wiki/Java_hashCode() and JavaDoc for Object.hashCode() here docs.oracle.com/javase/8/docs/api/java/lang/…
for(E e : lst) in main has to be an error in the specification. There is no reason to introduce a useless empty interface, and calling it E probably reflects that class Main was generic at some point.
@JimGarrison, that seems likely, unless it is intended as a puzzle for folks to solve.
It was definitely a puzzle. The main function was exactly as I wrote. But thanks for the help guys. I am enjoying this community. Hope to get more knowledge and then answer some questions too ;)
1

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.

Comments

0

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;
        }
    }

Comments

0

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());
        }

    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.