How to pass array parameter with inline declare? - java

I have a method as
private void show(Object[] arr) {
for (Object o : arr) {
System.out.println(o);
}
}
I would like to call this method as
// belows are not valid but I'd like to achieve
show({1,2,3});
show(new String["a","b","c"])
but I don't want to create an array to call this method. (Please don't be suggest to change the signature of my show method.This is just an example.Actual method that I use is from 3rd party lib.)
How can I achieve this by utility classes or anything else?

You can either use varargs as mentioned in the comments or declare the array this way:
show(new String[] {"a","b","c"})

Create a varargs wrapper method:
private void myShow(Object... arr){
show(arr);
}
// No change to your existing 3rd party method:
private void show(Object[] arr) {
for (Object o : arr) {
System.out.println(o);
}
}
You can then call the wrapper method like this:
myShow("a","b","c");
myShow(1,2,3,4);
Hope this helps!

What you are looking for is not a way to pass an array to a method without declare it, you are looking for a "single line data instatiation for array"... or by the real name "in-line declare"
show(new Object[]{"a","b","c"});

You can accomplish this by using varargs. A simple edit to your function will not only allow an array of objects but allow you to accomplish what you are looking for.
Instead of using Object[] use Object...

Related

GWT: how to pass java array into javascript native method?

I have a java array of String, and now I want to pass it into a JSNI function. I try to use JsArrayString in GWT, however I find that it can not be initialized directly, because it doesn't have a visible constructor. So how can I pass my String array into the JSNI function and use it in my javascript code? The code is looks like follows:
public void callJSNI() {
String[] stringArray = xxx;
//How should I convert the array into a JSNI-readable format here?
}
private native void JSNIMethod(JsArrayString array) /*-{
//some code to use the array in javascript
}-*/
The API does not provide an easy way to do it, you'd have to create a utility method that will:
Create a new JSNI array
Iterate over the Java array's arguments and populate the JSNI array
Something like this:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = createEmptyJsArrayString();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
private static native JsArrayString createEmptyJsArrayString() /*-{
return [];
}-*/;
As the OP suggested, we can, of course, skip the native initialization and use JsArrayString.createArray().
Now we can get rid of the native initialization, so our code reduces to this:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = JsArrayString.createArray().cast();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
The answer of Eliran Malka is a good starting point. But be aware that there is an extendend soloution that is much more efficient in some cases. That's why I create another answer.
The simple solution is this:
public static JsArrayString toJsArray(String[] input) {
JsArrayString jsArrayString = JsArrayString.createArray().cast();
for (String s : input) {
jsArrayString.push(s);
}
return jsArrayString;
}
The extended/more efficient solution needs some background knowledge...
The GWT compiler uses JS arrays when the Java code used Java arrays. So in this case you already have a JS array. But this can lead to side-effects that result in different behavior in Dev and Prod mode:
As we have real Java arrays in Dev mode, a conversion to a JS array by copying the values is always necessary. Manipulations in one of the arrays won't be visible to the other array.
In Prod mode if we use the Java array directly as JS array we would only have one array at all. So manipulations in either Java or JS code would affect the other world.
But if the following things apply to your use-case, you can use the array without creating another one:
One of these statements must be true
The array isn't manipulated by the JS code at all
The array isn't used by the Java code after it was given to the JSNI method
One of these statements must be true
The array is only used once in the JS code (the JS code doesn't create references to the array that last beyond the native method call)
The array isn't manipulated by Java code after the native call.
In this case you will not have side effects (different behavior in Dev and Prod mode) and the array can directly be used in the native code.
This kind of implementation is contained in GWT's JsArrayUtils. But unfortunately there is currently no implementation for String arrays. But the implementation will look like this:
public static JsArrayString readOnlyJsArray(String[] array) {
if (GWT.isScript()) {
return arrayAsJsArrayForProdMode(array).cast();
}
JsArrayString dest = JsArrayString.createArray().cast();
for (int i = 0; i < array.length; ++i) {
dest.push(array[i]);
}
return dest;
}
private static native JavaScriptObject arrayAsJsArrayForProdMode(Object array) /*-{
return array;
}-*/;
Finally I find the answer myself.
The JsArrayString can be "initiated" with JsArrayString.createArray(), and then you can do whatever manipulation as it is in javascript.

Call a function from a string array (Java or Groovy)

In Java, or Groovy, say I have a String array like
myArray = ["SA1", "SA2", "SA3", "SA4"]
I want to call a different function based off of each string.
class Myclass{
public static void SA1() {
//doMyStuff
}
public static void SA2() {
//doMyStuff
}
...etc
}
I would love to be able to loop through my array and call the functions that they pertain to without having to compare the string or make a case statement. For example is there a way to do something like the following, I know it doesn't currently work:
Myclass[myArray[0]]();
Or if you have suggestions of another way I can structure something similar.
In groovy you can do:
Myclass.(myArray[0])()
In Java you can do:
MyClass.class.getMethod(myArray[0]).invoke(null);
In Groovy, you can use a GString for dynamic method invocation:
myArray.each {
println Myclass."$it"()
}
You can, for instance, declare an interface such as:
public interface Processor
{
void process(String arg);
}
then implement this interface, for example in singletons.
Then create a Map<String, Processor> where keys are your strings, values are implementations and, when invoking:
Processor p = theMap.containsKey(theString)
? theMap.get(theString)
: defaultProcessor;
p.process(theString);
I suggest you look at Reflection APIs, to call methods at runtime
check Reflection docs
Class cl = Class.forName("/* your class */");
Object obj = cl.newInstance();
//call each method from the loop
Method method = cl.getDeclaredMethod("/* methodName */", params);
method.invoke(obj, null);

How to create an object in a utility class based on if statement in Java? (Or based on a particular string)

I would have a string that is parsed into an array, as shown here:
class Example extends ParentClass {
private String[] array;
public static Example parseString(String lineToParse) {
array = lineToParse.split("\");
}
public ObjectType1() { // arguments: String, String, String
}
public ObjectType2() { // arguments: String, String, String, double, double
}
}
What I'm wondering is could I do this?
if (array[0].equals("Test")) {
public ObjectType1()
}
Or is there a better way to do this?
I want to create various objects with different arguments each, and the first argument (array[0]) will be applicable to each object, so I was wondering if I could create objects within an if statement like this, or a switch (not sure if that would work either).
I believe a factory method would be useful for you, one that returns instances of classes according to the parameter received:
// ObjectType1, ObjectType2, ObjectType3 inherit from ObjectType
static ObjectType getInstance(String[] array) {
if (array[0].equals("Test"))
return new ObjectType1(array);
else if (array[0].equals("Test2"))
return new ObjectType2(array);
else
return new ObjectType3(array);
}
For the record, actually you can define a class inside a method, this is valid code in Java ... of course, that's hardly a good thing to do:
// ObjectType1, ObjectType2 inherit from ObjectType
public ObjectType example(String[] array) {
if (array[0].equals("Test")) {
class ObjectType1 {
ObjectType1(String[] array) {
}
}
return new ObjectType1(array);
}
else {
class ObjectType2 {
ObjectType2(String[] array) {
}
}
return new ObjectType2(array);
}
}
"Creating" an object means "instantiating it", with new:
ObjectType1 foo = new ObjectType1(...);
You can do that anywhere it's legal to instantiate a class, including in an if statement.
You cannot define classes in arbitrary locations, however.
If you just want to call a method (which should start with a lower-case letter if you want Java developers to understand what you're trying to do), you can call it from anywhere, including inside if statements.
This sounds like you may want to use a [static factory method][1].
[1]: http://en.m.wikipedia.org/wiki/Factory_method_pattern
I guess that you want to dynamically create objects based on a configuration file?
There are lots of ways to achieve this. One simple way is to use reflection to create the objects. Then you do not need any if/switch statements, and if you want to create a new type of object your code does not need to be changed.
Here are some examples for using reflection: Reflection API Code Samples

Java - ArrayList<Integer> as Parameter...?

I would like to know how to create a method which takes an ArrayList of Integers (ArrayList) as a parameter and then display the contents of the ArrayList?
I have some code which generates some random numbers and populates the ArrayList with the results, however I keep having errors flag up in eclipse when attempting to create this particular method.
Here is what I have so far:
public void showArray(ArrayList<Integer> array){
return;
}
I know that it is very basic, but I am unsure exactly how to approach it - could it be something like the following?
public void showArray(ArrayList<Integer> array){
Arrays.toString(array);
}
Any assistance would be greatly appreciated.
Thank you.
I'm assuming this is a learning exercise. I'll give you a few hints:
Your method is named showArray, but an ArrayList<T> is of type List<T>, and is not an array. More specifically it is a list that is implemented by internally using an array. Either change the parameter to be an array or else fix the name of the method.
Use an interface if possible instead of passing a concrete class to make your method more reusable.
Minor point: It may be better to have your method return a String, and display the result outside the method.
Try something like this:
public void printList(List<Integer> array) {
String toPrint = ...;
System.out.println(toPrint);
}
You can use a loop and a StringBuilder to construct the toPrint string.
Is there any reason why System.out.println( array ); wouldn't work for you?
Output will be like:
[1, 2, 3]
If you are looking to print the array items, try
public void showArray(ArrayList<Integer> array){
for(int arrayItem : array)
{
System.out.println(arrayItem);
}
}
This sounds like someone wants us to do their homework. You don't have to return anything if you are just displaying it, and if the method has a void return type. I don't know exactly what you want but is it something along the lines of System.out.println(array.elementAt(index))? then you would need a loop.

Can Java store methods in arrays?

Well I wrote some code and all I was doing was for loops, but changing which method I called. I tried using a for loop so it'd be a bit neater (and out of curiosity to see if it could be done), but it doesn't compile when I do it this way, because it doesn't recognize an item in an array as a method, I think. This is what I have:
String[] moveArray = {moveRight,moveDown,moveLeft,moveUp};
for (i = 0; i < 4; i++) {
while (myWumpus.moveArray[i]) {
myWumpus.moveArray[i];
generator.updateDisplay();
}
}
When I try compile I get
not a statement myWumpus.moveArray[i]();
';' expected myWumpus.moveArray[i]();
(It refers to the first statement in the while loop)
So, I think it's maybe because I'm making it an Array of type String? Is there a type Method? Is this at all possible? Any solutions welcome :). Also, I can get it to work using 4 while loops, so you don't need to show me that solution.
You cannot store methods directly in arrays. However you can store objects, which implement the same method differently. For example:
Mover[] moveArray = {new RightMover(), new DownMover() new LeftMover(), new UpMover() };
for (i = 0; i < 4; i++) {
while (myWumpus.moveArray[i]) {
moveArray[i].move();
generator.updateDisplay();
}
}
Yes, you can store methods in arrays using Reflection, however it is likely that what you actually want to do in this situation is use polymorphism.
As an example of polymorphism in relation to your problem - say you created an interface as follows:
public interface MoveCommand {
void move();
}
You can then create implementations as follows:
public class MoveLeftCommand implements MoveCommand {
public void move() {
System.out.println("LEFT");
}
}
etc. for the other move options. You could then store these in an MoveCommand[] or collection like a List<MoveCommand>, and then iterate over the array/collection calling move() on each element, for example:
public class Main {
public static void main(String[] args) {
List<MoveCommand> commands = new ArrayList<MoveCommand>();
commands.add(new MoveLeftCommand());
commands.add(new MoveRightCommand());
commands.add(new MoveLeftCommand());
for (MoveCommand command:commands) {
command.move();
}
}
}
Polymorphism is very powerful, and the above is a very simple example of something called the Command Pattern. Enjoy the rest of your Wumpus World implementation :)
You can't store methods in arrays in Java, because methods aren't first-class objects in Java. It's a reason some people prefer to use other languages like Python, Scheme, etc.
The work-around is to create an interface which contains one method, then create four classes implementing that interface - the MoveRight, MoveLeft, etc... classes. Then you can store instances of those classes in your array and call them all the same way.
You can't call methods like that. But you can using reflection:
Just change the first line in the while-loop to:
Method m = myWumps.getClass().getMethod(moveArray[i]); // if the method is void
m.invoke(myWumps);
(you will have to declare/catch a few exceptions)
But you'd better avoid reflection, and use the Command pattern instead.
Updated answer for Java 8 and onwards-
Since the introduction of lambda expressions and method references in Java 8, storing various methods in variables is now possible. One main issue is that arrays don't currently support generic objects in Java, which makes storing the methods in arrays less doable. However they can be stored in other data structures like a List.
So for some simple examples you can write something like:
List<Comparator<String>> stringComparators = new ArrayList<>();
Comparator<String> comp1 = (s1, s2) -> Integer.compare(s1.length(), s2.length());
stringComparators.add(comp1);
or
List<Consumer<String>> consumers = new ArrayList<>();
Consumer<String> consumer1 = System.out::println;
consumers.add(consumer1);
and then loop/iterate through the List to get the methods.

Categories