Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 10 of 10

Thread: Creating generic version of methods

  1. #1
    Member
    Join Date
    Jun 2014
    Posts
    33
    My Mood
    Inspired
    Thanks
    9
    Thanked 1 Time in 1 Post

    Default Creating generic version of methods

    So I have this class containing all my Enum types, also including methods for fetching Enum types based on their title attribute:
    abstract class Enums {
     
    	static private Landmass getLandmass(String name) {
    		for ( Landmass l : Landmass.values( ) ) {
    			if(l.title.equals(name)){
    				return l;
    			}
    		}
    		return null;
    	}
     
    	static private Attribute getAttribute(String name) {
    		for ( Attribute a : Attribute.values( ) ) {
    			if(a.title.equals(name)){
    				return a;
    			}
    		}
    		return null;
    	}
    The second method (getAttribute) is created by copy-paste and I also need to repeat this exercise with several other types of Enums. This seems like a waste of code however.

    Instead, I thought I'd create a generic method for fetching any type of Enums. As far as I could follow the tutorial @ Oracle I need a generic class for this. Thus the EnumHelper class:

    abstract class EnumHelper<T> {
     
    	private T getEnum(T type, String name) {
    		for ( type t : type.values( ) ) {
    			if(t.title.equals(name)){
    				return t;
    			}
    		}
    		return null;
    	}
    }

    This, however, doesn't compute:

    horoscope\Enums.java:234: error: cannot find symbol
                    for ( type t : type.values( ) ) {
                          ^
      symbol:   class type
      location: class EnumHelper<T>
      where T is a type-variable:
        T extends Object declared in class EnumHelper
    horoscope\Enums.java:234: error: cannot find symbol
                    for ( type t : type.values( ) ) {
                                       ^
      symbol:   method values()
      location: variable type of type T
      where T is a type-variable:
        T extends Object declared in class EnumHelper
    2 errors
    To be honest I haven't been able to make much sense of the documentation on generics, thus its no surprise I'm stuck. Hopefully someone will be able to explain the logic behind this generics thing.
    Last edited by Baldyr; July 21st, 2014 at 05:00 PM.


  2. #2
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Creating generic version of methods

    Well, your enhanced for() loop is not correct, so start there. I'm not sure that'll be the only fix, but maybe that'll get you moving forward.

  3. #3
    Member
    Join Date
    Jun 2014
    Posts
    33
    My Mood
    Inspired
    Thanks
    9
    Thanked 1 Time in 1 Post

    Default Re: Creating generic version of methods

    Yeah? Did this correct the error?
    	private T getEnum(T type, String name) {
    		for ( T t : type.values( ) ) {
    			if(t.title.equals(name)){
    				return t;
    			}
    		}
    		return null;
    	}
    Other than that, I can't spot my error...

    Anyhow, this is still the complaint:
    horoscope\Enums.java:234: error: cannot find symbol
                    for ( T t : type.values( ) ) {
                                    ^
      symbol:   method values()
      location: variable type of type T
      where T is a type-variable:
        T extends Object declared in class EnumHelper
    horoscope\Enums.java:235: error: cannot find symbol
                            if(t.title == name){
                                ^
      symbol:   variable title
      location: variable t of type T
      where T is a type-variable:
        T extends Object declared in class EnumHelper
    2 errors
    So basically, how do I make the compiler accept that the names type and t will have these fields called values and title respectively at runtime?

    --- Update ---

    Going forward with my Java studies, I now realize I really don't need a generic class for this. Instead I added a generic method in my Enums class:
    abstract class Enums {
     
    	static private <E> Class getEnum(Class<E> type, String name) {
    		for ( type t : type.values( ) ) {
    			if(t.title.equals(name)){
    				return t;
    			}
    		}
    		return null;
    	}
    Well, this still doesn't compute:
    horoscope\Enums.java:6: error: cannot find symbol
                    for ( type t : type.values( ) ) {
                          ^
      symbol:   class type
      location: class Enums
    horoscope\Enums.java:6: error: cannot find symbol
                    for ( type t : type.values( ) ) {
                                       ^
      symbol:   method values()
      location: variable type of type Class<E>
      where E is a type-variable:
        E extends Object declared in method <E>getEnum(Class<E>,String)
    2 errors
    I just guessing here as to the generics stuff... First of all, nor the return value or the parameter should really be Class, right? I tried Object and Enum and they didn't work, so I'm stuck again.

  4. #4
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Creating generic version of methods

    Once again, your enhanced for() loop is incorrect. Review the required structure and fix it.

  5. #5
    Member
    Join Date
    Jun 2014
    Posts
    33
    My Mood
    Inspired
    Thanks
    9
    Thanked 1 Time in 1 Post

    Default Re: Creating generic version of methods

    Quote Originally Posted by GregBrannon View Post
    Once again, your enhanced for() loop is incorrect. Review the required structure and fix it.
    Sorry, but I'm not seeing any error in the code. I copy-pasted the getLandmass() method and used the same for() loop and only renamed the values. Since it works fine for the original method I'm assuming that the expression is legal, not?

    Please explain what I'm missing! (This is NOT part of any school assignment - I'm just trying to learn Java for my own entertainment. Once I resort to bothering you with my project I've reached a point of not being very entertained any more.)

    Thank you in advance.
    Last edited by Baldyr; July 22nd, 2014 at 04:53 AM.

  6. #6
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Creating generic version of methods

    Compare your statement:

    for ( type t : type.values( ) )

    to the documentation for the enhanced for() loop.

    Hints: Is 'type' really a Type? Using proper capitalization per Java's naming conventions will cause these kind of errors to jump off the page at you when you're more familiar.

  7. #7
    Member
    Join Date
    Jun 2014
    Posts
    33
    My Mood
    Inspired
    Thanks
    9
    Thanked 1 Time in 1 Post

    Default Re: Creating generic version of methods

    I'm afraid I'm a bit lost. This is what I got now:
    abstract class Enums {
     
    	static private <E> Class getEnum(Class<E> enumType, String name) {
    		for ( enumType t : enumType.values( ) ) {
    			if(t.title.equals(name)){
    				return t;
    			}
    		}
    		return null;
    	}	
     
    	static private Landmass getLandmass(String name) {
    		for ( Landmass l : Landmass.values( ) ) {
    			if(l.title.equals(name)){
    				return l;
    			}
    		}
    		return null;
    	}
    The difference between these two methods, as far as I can fathom, is that the first one takes an additional parameter (EnumType) corresponding to a Enum type, while the second one deals with Landmass Enum types exclusively.

    Sure, I'm not getting the whole generics thing yet, but fail to see anything wrong with my for() loops. The second method seems to work, at least.

    Regarding "Type" and "type", I might have used a keyword or a built-in class name by mistake. I changed the identifier to enumType, which shouldn't cause any issues, right?

  8. #8
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Creating generic version of methods

    I'm not sure what you're trying to do. Can you post a full program - even a broken one - focused on simply doing the one thing you're trying to do that could be used to understand what the objective is?

  9. #9
    Member
    Join Date
    Jun 2014
    Posts
    33
    My Mood
    Inspired
    Thanks
    9
    Thanked 1 Time in 1 Post

    Default Re: Creating generic version of methods

    Sure
    abstract class Enums{
     
    	public enum TimeOWeek{
    		MONDAY ("måndag"),
    		TUESDAY ("tisdag"),
    		WEDNESDAY ("onsdag"),
    		THURSDAY ("tordag"),
    		FRIDAY ("fredag"),
    		SATURDAY ("lördag"),
    		SUNDAY ("söndag"),;
     
    		public final String title;
     
    		TimeOWeek (String name) {
    			this.title = name;
    		}
    	}
     
    	public enum TimeODay{
    		DAWN ("gryning"),
    		DAY ("dag"),
    		DUSK ("skymning"),
    		NIGHT ("natt"),;
     
    		public final String title;
     
    		TimeODay (String name) {
    			this.title = name;
    		}
    	}
     
    	static TimeOWeek getWeekday(String name) {
    		for ( TimeOWeek t : TimeOWeek.values( ) ) {
    			if(t.title.equals(name)){
    				return t;
    			}
    		}
    		return null;
    	}
     
    	static TimeODay getTime(String name) {
    		for ( TimeODay t : TimeODay.values( ) ) {
    			if(t.title.equals(name)){
    				return t;
    			}
    		}
    		return null;
    	}
    }
     
    public class TimesAndDays {
     
    	public static void main(String []args) {
    		for( String name : args ){
    			System.out.printf("\n");
    			if(Enums.getWeekday(name) != null){
    				System.out.printf(name + " corresponds with " + Enums.getWeekday(name));
    			}else if(Enums.getTime(name) != null){
    				System.out.printf(name + " corresponds with " + Enums.getTime(name));
    			}
    			else{
    				System.out.printf(name + " corresponds with nothing");
    			}
    		}
    	}
    }
    So if I run the application from Command Prompt I get:
    $java TimesAndDays lördag midnatt skymning
    $
    $l÷rdag corresponds with SATURDAY
    $midnatt corresponds with nothing
    $skymning corresponds with DUSK
    This verifies that the methods Enums.getWeekday() - which returns a TimeOWeek Enum Type - and Enums.getTime() - which returns a TimeODay Enum Type - works.

    Now, I wanna get rid of both of these methods and instead have a generic Enums.getEnum() method:
    	public static void main(String []args) {
    		for( String name : args ){
    			System.out.printf("\n");
    			if(Enums.getEnum(Enums.TimeOWeek, name) != null){
    				System.out.printf(name + " corresponds with " + Enums.getEnum(Enums.TimeOWeek, name));
    			}else if(Enums.getEnum(Enums.TimeODay, name) != null){
    				System.out.printf(name + " corresponds with " + Enums.getEnum(Enums.TimeODay, name));
    			}
    			else{
    				System.out.printf(name + " corresponds with nothing");
    			}
    		}
    	}
    So I need to write a generic Enums.getEnum() method. This is what I tried:
    	static <T> Enum getEnum(Enum<T> enumType, String name) {
    		for ( Enum t : enumType.values( ) ) {
    			if(t.title.equals(name)){
    				return t;
    			}
    		}
    		return null;
    	}
    Since I don't know what I'm doing, I get this from the compiler. Dunno what it means.
    TimesAndDays.java:32: error: type argument T is not within bounds of type-variable E
            static <T> Enum getEnum(Enum<T> enumType, String name) {
                                         ^
      where T,E are type-variables:
        T extends Object declared in method <T>getEnum(Enum<T>,String)
        E extends Enum<E> declared in class Enum
    TimesAndDays.java:33: error: cannot find symbol
                    for ( Enum t : enumType.values( ) ) {
                                           ^
      symbol:   method values()
      location: variable enumType of type Enum<T>
      where T is a type-variable:
        T extends Object declared in method <T>getEnum(Enum<T>,String)
    TimesAndDays.java:34: error: cannot find symbol
                            if(t.title.equals(name)){
                                ^
      symbol:   variable title
      location: variable t of type Enum
    TimesAndDays.java:65: error: cannot find symbol
                            if(Enums.getEnum(Enums.TimeODay, name) != null){
                                                  ^
      symbol:   variable TimeODay
      location: class Enums
    TimesAndDays.java:66: error: cannot find symbol
                                    System.out.printf(name + " corresponds with " + Enums.getEnum(Enums.TimeODay, name));
                                                                                                       ^
      symbol:   variable TimeODay
      location: class Enums
    TimesAndDays.java:67: error: cannot find symbol
                            }else if(Enums.getEnum(Enums.TimeOWeek, name) != null){
                                                        ^
      symbol:   variable TimeOWeek
      location: class Enums
    TimesAndDays.java:68: error: cannot find symbol
                                    System.out.printf(name + " corresponds with " + Enums.getEnum(Enums.TimeOWeek, name));
                                                                                                       ^
      symbol:   variable TimeOWeek
      location: class Enums
    7 errors

  10. #10
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Creating generic version of methods

    I think this article covers what you're trying to do, but I didn't work through it to verify. If this article is not quite right, you might try searching 'java generic enum' and mining those results.

    Good luck!

Similar Threads

  1. Creating objects from methods
    By fahman_khan75@yahoo.com in forum What's Wrong With My Code?
    Replies: 7
    Last Post: March 21st, 2014, 12:00 PM
  2. Creating methods with Arrays
    By incxx in forum What's Wrong With My Code?
    Replies: 4
    Last Post: September 23rd, 2013, 08:44 PM
  3. Creating classes with generic objects
    By rbt in forum Collections and Generics
    Replies: 2
    Last Post: April 23rd, 2012, 08:08 PM
  4. Creating array from generic type objects?
    By AndrewMiller in forum What's Wrong With My Code?
    Replies: 4
    Last Post: November 13th, 2010, 09:22 PM