Simple question about Java Methods

D

Danger_Duck

In paramaters, can I specify what type of String I want? For example,
can I do something like:

public void method1(static final String s) {
//do something
}

I suppose my bigger question is how you specify a fixed value without
resorting to Java's ugly implementation of enumarations.

For instance, I want to have a class that will graph functions based
on type, but one of the parameters is "sin, square, sawtooth" etc.

Right now, I have declarators like 'public static final String sin =
"SinWave"; ' at the top of my class, and would like it so that the
constructor only accepts static final strings. Of course, he might use
such strings from different classes to my dismay, but at least I will
filter it out a bit.

So am I able to get more specific about the parameters I want to take
in? My gut feeling is no since the above code looks atrocious, but I
would like to hear how one goes about such things in a simple manner
(again, without enumerations).
 
J

Joshua Cranmer

Danger_Duck said:
In paramaters, can I specify what type of String I want? For example,
can I do something like:

public void method1(static final String s) {
//do something
}

The easiest way is something like this:

private static String[] acceptable = Arrays.sort(new String[] {
"sin", "square", "sawtooth" });

public void method1(String s) {
if (acceptable.binarySearch(s) < 0)
throw IllegalArgumentException(s + "is not acceptable!");
}

Yes, it's runtime, not compile-time, but by ruling out enums, you've
pretty much ruled out all compile-time tests, unless you use annotations
and static analysis.
 
M

Mike Schilling

Joshua said:
Danger_Duck said:
In paramaters, can I specify what type of String I want? For
example,
can I do something like:

public void method1(static final String s) {
//do something
}

The easiest way is something like this:

private static String[] acceptable = Arrays.sort(new String[] {
"sin", "square", "sawtooth" });

public void method1(String s) {
if (acceptable.binarySearch(s) < 0)
throw IllegalArgumentException(s + "is not acceptable!");
}

Yes, it's runtime, not compile-time, but by ruling out enums, you've
pretty much ruled out all compile-time tests, unless you use
annotations and static analysis.

Or you could use an Enum, which make the check compile time. I don't
know why that would be (in the OP's words) "uglier" than this.
 
D

Daniel Pitts

Danger_Duck said:
In paramaters, can I specify what type of String I want? For example,
can I do something like:

public void method1(static final String s) {
//do something
}

I suppose my bigger question is how you specify a fixed value without
resorting to Java's ugly implementation of enumarations.

For instance, I want to have a class that will graph functions based
on type, but one of the parameters is "sin, square, sawtooth" etc.

Right now, I have declarators like 'public static final String sin =
"SinWave"; ' at the top of my class, and would like it so that the
constructor only accepts static final strings. Of course, he might use
such strings from different classes to my dismay, but at least I will
filter it out a bit.

So am I able to get more specific about the parameters I want to take
in? My gut feeling is no since the above code looks atrocious, but I
would like to hear how one goes about such things in a simple manner
(again, without enumerations).
You've just said something akin to "I want to pound nails into a board,
but I don't want to use an ugly hammer."

enumerations are not ugly:

public class Grapher {
public enum WaveType {
sine, square, sawtooth
}

public void graph(WaveType type) { ... }
}

This is faster than dealing with String, and more type-safe as well.
Even better, add a method to each:

public class Grapher {
public enum WaveType {
sine {
public void graph(Grapher target) { target.drawSine(); }
},
square {
public void graph(Grapher target) { target.drawSquare(); }
},
sawtooth {
public void graph(Grapher target) { target.drawSawtooth(); }
}
;
public abstract void graph(Grapher target);
}

public void graph(WaveType type) { type.graph(this); }
}

Now, if you really don't want to use enum (I can't imagine why), you
*can* create your own class WaveType, which emulates enums, but thats
just silly unless you want to give your clients the ability to extend them.

So, now having given you what I think is best, can you tell me why you
want to avoid enums? What about this is ugly to you?

Good luck,
Daniel.
 
S

Stefan Ram

Danger_Duck said:
So am I able to get more specific about the parameters I want to take
in?

The methods »method1« below will accept arguments of type
»StaticString«:

class StaticString
{ private java.lang.String string;
public StaticString( final java.lang.String string )
{ this.string = string; }}

public class Main
{ public static final StaticString sin = new StaticString( "SinWave" );
public static void method1( final StaticString string ){}
public static void main( final java.lang.String[] args )
{ method1( sin ); }}

The call »method1( "SinWave" )« would be rejected by the
compiler.
 
D

Danger_Duck

You've just said something akin to "I want to pound nails into a board,
but I don't want to use an ugly hammer."

enumerations are not ugly:

public class Grapher {
    public enum WaveType {
       sine, square, sawtooth
    }

    public void graph(WaveType type) { ... }

}

This is faster than dealing with String, and more type-safe as well.
Even better, add a method to each:

public class Grapher {
     public enum WaveType {
       sine {
          public void graph(Grapher target) { target.drawSine(); }
       },
       square {
          public void graph(Grapher target) { target.drawSquare(); }
       },
       sawtooth {
          public void graph(Grapher target) { target.drawSawtooth(); }
       }
       ;
         public abstract void graph(Grapher target);
     }

     public void graph(WaveType type) { type.graph(this); }

}

Now, if you really don't want to use enum (I can't imagine why), you
*can* create your own class WaveType, which emulates enums, but thats
just silly unless you want to give your clients the ability to extend them.

So, now having given you what I think is best, can you tell me why you
want to avoid enums?  What about this is ugly to you?

Good luck,
Daniel.

Doh!, I guess enumerations in Java aren't as bad as I thought, in
addition to not being able to interchange them with integers, I was
always turned off by the below link, but turns out that I misread it:
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html

I had thought that a client program had to instantiate an instance of
the enumeration, then call a method on it. Now I realize that I
thought the class "EnumTest" was the enumeration :)

While I still don't like how Java does not provide direct access to
the enumeration like in C, your way works fine for what I want here,
and it looks like I was too quick to bash what I had in fact misread.
 
J

Joshua Cranmer

Danger_Duck said:
Doh!, I guess enumerations in Java aren't as bad as I thought, in
addition to not being able to interchange them with integers,

class Test {
enum Values { A, B, C; }
public static void main(String[] args) {
System.out.println(A.ordinal());
}
}

Alternatively:
enum CustomValues {
A(1),
B(20),
C(100);

public final int value;
CustomValues(int value) { this.value = value; }
}

Another thread recently pondered the capabilities of enums, but I don't
remember which one...
 
D

Danger_Duck

Danger_Duck said:
Doh!, I guess enumerations in Java aren't as bad as I thought, in
addition to not being able to interchange them with integers,

class Test {
   enum Values { A, B, C; }
   public static void main(String[] args) {
     System.out.println(A.ordinal());
   }

}

Alternatively:
enum CustomValues {
   A(1),
   B(20),
   C(100);

   public final int value;
   CustomValues(int value) { this.value = value; }

}

Another thread recently pondered the capabilities of enums, but I don't
remember which one...

Oh boy. I'm sorry Java enum. I judged you from gossip without ever
meeting you.
 
M

Mark Space

Danger_Duck said:
Doh!, I guess enumerations in Java aren't as bad as I thought, in
addition to not being able to interchange them with integers, I was
always turned off by the below link, but turns out that I misread it:
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html

That there is some pretty complex use of enums.

All you really need is:

enum Waves { sine, square, sawtooth }

Then you can do things like specify them as parameters to your method

public void method1( Waves w ) {
switch (w) {
case sine:
// Draw a sine wave
case square:
// Draw a square wave
case sawtooth:
// Draw a sawtooth wave
}
}

This is pretty unsophisticated use of enums, but it works. If you don't
like the examples up-thread (which are better, btw) then this will work
just fine until you get used to doing more tricky things with enums.

I had thought that a client program had to instantiate an instance of
the enumeration, then call a method on it. Now I realize that I
thought the class "EnumTest" was the enumeration :)


Nope, you don't have to do that if you don't want to. You can, and it
can often be better to do so, but if you don't understand it then I
would just concentrate on writing code you understand and can maintain
and worry about the tricky stuff later.

While I still don't like how Java does not provide direct access to
the enumeration like in C, your way works fine for what I want here,
and it looks like I was too quick to bash what I had in fact misread.


What kind of direct access are you looking for? It's easy to concert
enums into integers: sine.ordinal() will convert "sine" into a number. I
don't see immediately how to go in the other direction, but I think
Waves.values() will always return an array in ordinal order.
 
D

Danger_Duck

That there is some pretty complex use of enums.

All you really need is:

   enum Waves { sine, square, sawtooth }

Then you can do things like specify them as parameters to your method

   public void method1( Waves w ) {
         switch (w) {
             case sine:
             // Draw a sine wave
             case square:
             // Draw a square wave
             case sawtooth:
             // Draw a sawtooth wave
         }
    }

This is pretty unsophisticated use of enums, but it works.  If you don't
like the examples up-thread (which are better, btw) then this will work
just fine until you get used to doing more tricky things with enums.




Nope, you don't have to do that if you don't want to.  You can, and it
can often be better to do so, but if you don't understand it then I
would just concentrate on writing code you understand and can maintain
and worry about the tricky stuff later.




What kind of direct access are you looking for?  It's easy to concert
enums into integers: sine.ordinal() will convert "sine" into a number. I
don't see immediately how to go in the other direction, but I think
Waves.values() will always return an array in ordinal order.

Alright, maybe someone can tell me how to do this with enums:

I have a combo-box (I'm using Eclipse, so
org.eclipse.swt.widgets.Combo.Combo) that contains the elements "Sin",
"Square", and "Sawtooth".

Based on the selection, I want to create a different function. This
was the original reason I was using public static final Strings
instead of enums: since the Combo.getText() method returns a String, I
was just going to hardwire selections as public static final Strings
in my FunctionGenerator class

ie, FunctionGenerator fg = new
FunctionGenerator(combobox1.getText(), ...);
and I would perform a check of matching strings....crude I know.

How would I go about doing this using Enums rather than static final
Strings?
 
S

Stefan Ram

Danger_Duck said:
org.eclipse.swt.widgets.Combo.Combo [...]
Based on the selection, I want to create a different function.

I don't know org.eclipse, but you can create function objects

interface Function { public double valueAt( final double x ); }

class Sin implements Function
{ public double valueAt( final double x )
{ return java.lang.Math.sin( x ); }}

....

final Function sin = new Sin();

....

And then you can store the object »sin« in the combo box
field, so that it is returned upon selection - if org.eclipse
supports this.

So there will be no need to »create« anything, the function
object can be used directly as sent by the field, possibly
after a downcast from »Object« to »Function«.
~~

It is a big shame than Java SE does not define common interfaces
such as »Function<S,T>«. This would increase interoperability
between source code from different sources as they could then
all share these interfaces. Nowadays, unfortunately, everyone
is still forced to define his own interface. For example,

http://www.purl.org/stefan_ram/html/ram.jar/de/dclj/ram/Function.html
 
M

Mark Space

Danger_Duck said:
Alright, maybe someone can tell me how to do this with enums:

I have a combo-box (I'm using Eclipse, so
org.eclipse.swt.widgets.Combo.Combo) that contains the elements "Sin",
"Square", and "Sawtooth".

Based on the selection, I want to create a different function. This
was the original reason I was using public static final Strings
instead of enums: since the Combo.getText() method returns a String, I

I don't know SWT, but strings are easy to deal with:

Waves ws = Waves.valueOf("sine");

would get you the enum from the string, and:

Waves w = Waves.valueOf( combobox1.getText() );

Would do the same thing based on the code you have. (I changed the name
from a class to a variable because even though I don't know SWT I'm
pretty sure getText() is not a static method.)

Stefan is right, there's a better way besides a switch statement to do
actually draw the waveform. However, if you don't feel confortable yet
with adding methods to a Java enum, switch will work fine until you do.
Just be aware that there are other ways, and resolve to come back and
revist it when you feel more comfortable with Java.

was just going to hardwire selections as public static final Strings
in my FunctionGenerator class

ie, FunctionGenerator fg = new
FunctionGenerator(combobox1.getText(), ...);
and I would perform a check of matching strings....crude I know.

FunctionGenerator fg = new
FunctionGenerator( Waves.valueOf( combobox1.getText() ) );
 
M

Mark Space

Mark said:
FunctionGenerator fg = new
FunctionGenerator( Waves.valueOf( combobox1.getText() ) );

I was going fast and I forgot to mention: case does matter. You'll have
to use .toLowerCase() or toUpperCase() in the strings to match case,
depending how you declare the enum. E.g., sine vs. SINE.
 
R

Roedy Green

I suppose my bigger question is how you specify a fixed value without
resorting to Java's ugly implementation of enumarations.

There were two techniques used prior to enumerations:

1. use strings

2. use named constants e.g. public static final int STRAWBERRY = 3;

The problem is, you don't get type safety.

Enumerations are quirky, granted, but once you get to know them they
are a slick tool.

See http://mindprod.com/jgloss/enumeration.html
 
C

Chronic Philharmonic

Stefan Ram said:
Danger_Duck said:
org.eclipse.swt.widgets.Combo.Combo [...]
Based on the selection, I want to create a different function.

I don't know org.eclipse, but you can create function objects

interface Function { public double valueAt( final double x ); }

class Sin implements Function
{ public double valueAt( final double x )
{ return java.lang.Math.sin( x ); }}

...

final Function sin = new Sin();

...

And then you can store the object »sin« in the combo box
field, so that it is returned upon selection - if org.eclipse
supports this.

So there will be no need to »create« anything, the function
object can be used directly as sent by the field, possibly
after a downcast from »Object« to »Function«.

The enums will do this also. I always found this tutorial to be quite
helpful: http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
 
N

Nigel Wade

Mark said:
I don't know SWT, but strings are easy to deal with:

Waves ws = Waves.valueOf("sine");

would get you the enum from the string, and:

Waves w = Waves.valueOf( combobox1.getText() );

Would do the same thing based on the code you have. (I changed the name
from a class to a variable because even though I don't know SWT I'm
pretty sure getText() is not a static method.)

Stefan is right, there's a better way besides a switch statement to do
actually draw the waveform. However, if you don't feel confortable yet
with adding methods to a Java enum, switch will work fine until you do.
Just be aware that there are other ways, and resolve to come back and
revist it when you feel more comfortable with Java.



FunctionGenerator fg = new
FunctionGenerator( Waves.valueOf( combobox1.getText() ) );

Why use Strings in the JComboBox? Enums can do pretty much all the work for you.

You can use any Object, including Enums (Waves in this case), in a JComboBox.
JComboBox uses an Object's toString() method to display the text in the visual
component. Rather than using the JComboBox.getText() method use the
getSelectedItem() and you get back the selected Waves item that you actually
want.

If you capitalize the Waves:
public enum Waves { Sine, Square, Sawtooth; }

the capitalized strings will be displayed in the JComboBox.

JComboBox box;
...
box.addItem(Waves.Sine);
box.addItem(Waves.Square);
box.addItem(Waves.Sawtooth);
...
private void jComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
JComboBox box = (JComboBox) evt.getSource();
Waves selectedWave = (Waves) box.getSelectedItem();
System.out.println("Selected waveform is : "+selectedWave);
FunctionGenerator fg = new FunctionGenerator( selectedWave }
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top