Passing arguments to a Java method - java

I need to pass arguments to a java method func(String, String...).
Problem is I have all the strings I need to pass as arguments, but they are in an ArrayList container.
For Example:
for(...some condition...)
{
//the other method returns an ArrayList with different size in each iteration
ArrayList <String> values = someOtherMethod();
func(values) //values is an ArrayList<String>, containing all the arguments
}
I get an error saying that ArrayList<String> can't be converted to String.
The size of values changes, because the someOtherMethod method returns a container with different size each iteration, so I can't pass values[0], values[1], etc as arguments.
I'm guessing the func wants an X amount of String variables, but I don't know how to convert a container to an X amount of variables when the size of the container isn't constant.

The "..." operator accepts arrays, so you could just do the following:
ArrayList <String> values = someOtherMethod();
func(values.toArray(new String[values.size()]);

It's a little bit complex as func requires one String and then an arbitrary number of additional Strings:
List<String> values = someOtherMethod();
if (values.isEmpty()) {
// handle special case
} else{
func(values.get(0), values.subList(1, values.size()).toArray(new String[]));
}

I'm guessing the func wants an X amount of String variables,
I guess you are looking for Varargs.
Change your function signature to accept as
public someReturnType func(String... vargs) { }
Which takes variable length of args as parameter.
And then inside the method ,you can access them like
for (String currentarg: args) {
// do something with currentarg
}
As a side note : Available from version 1.5 only.
Learn more from docs about Varargs

Related

Receiving String... parameters and passing its values to other method that receives String ...parameters

private String createURI (String URL , String... parameters) {
if (parameters != null && parameters.length > 0) {
return String.format(URL, "5435534", "John" , parameters[0].toString());
}
return String.format(URL, "5435534", "John");
}
I created a method that should support in getting URL or URL+additional parameters and create from them a URL by the passed values.
of course the amount of %s in the URL should fit the amount of the parameters.
I use it like that:
createURI ("%s/call/%s") ==> 5435534/call/John
createURI ("%s/call/%s/%s" , "familyName") ==> 5435534/call/John/familyName
I didnt want to created something like this:
String createURI (String URL , String parameter) and just pass empty string when I don't want to use it and then check in the method whether the text is empty or not, and call the method the next way:
createURI ("%s/call/%s" , "")
createURI ("%s/call/%s/%s" , "FamilyName")
my question is how can I improve it by sending exactly the arguments received to the String.format method without explicitly sending the [0] item - I don't want to check the values, the String.format doing it already but to String values. if I just passing the parameters as is (type String...) to String.format(URL, "5435534", parameters) it doesn't receive the actual string value but the full object.
private String createURI (String URL , String... parameters) {
ArrayList<String> strs = new ArrayList<>();
strs.add("5435534");
strs.add("John");
strs.addAll(Arrays.asList(parameters);
return String.format(URL, strs.toArray());
}
You can join all parameters to List and convert it to Array for String.format. This way will no if for this. and need to call out: varargs default size is 0.
String.format() (without a Locale parameter) takes two arguments: a format string, and an array of Object:
public static String format(String format,
Object... args)
Since the second argument uses ... notation, you have two options for passing the second argument: either you can pass it an Object[], or you can pass it zero or more arguments of any type that will then be bundled up into an Object[]. Those are the only two choices. You can't, say, pass two arguments, and then pass an array that the method will see as the third, fourth, etc. argument. That array will be seen as a single argument.
However, you can create your own Object[] array, set the first two elements of the array, and copy the remainder in, something like:
Object[] formatParameters = new Object[parameters.length + 2];
formatParameters[0] = "5435534";
formatParameters[1] = "John";
for (int i = 0; i < parameters.length; i++) {
formatParameters[i + 2] = parameters[i];
}
return String.format(URL, formatParameters);
Note that formatParameters has to be Object[] for this to work (I don't think it will work with String[]). This is to get the compiler to realize that you're passing an array of parameters, instead of a single parameter whose type happens to be an array.
(Note: There should be methods in Arrays that could copy from parameters to formatParameters without a loop, but I don't feel like looking them up right now.)

create variables dynamically, Data Types of java Variables

As we know variables are of different data types, but which data type are their names of?
As it seems they are String, but if they are String then this should be allowed:
int i=6;
String [] arr+i;
...as we can add an int to a String.
So if these are not String then what are they?
And if we want to create variable names dynamically how can we create it?
By dynamically I mean whenever the user clicks on a specific JComponent, a new variable is created, like:
int i=0;
//on first click
String str+i; ///str0
i++;
///on 2nd click
String str+i; ////str1
///i++;
How can I do it?
You can not create dynamic variables in Java because Java isn't a scripting language. YOu need to create variables in source code. But Java provides other ways to do this.
You can use arrays or Map<String, String> etc for this purpose.
Map<String, String> map= new HashMap<>();
int i=0;
while(true) {
// you can use whatever condition you need
details.put("key" + i, "val: "+i);
i++
// some condition to break the loop
}
Java identifiers are not of any type and definitely not String. You can't do this in java, instead, you use a data structure to use these values like ArrayList<String>and store the nth String in the nth index of the data structure like so:
ArrayList<String> strings= new ArrayList<String>(); // Create a new empty List
strings.add(index, string); //add string at index position of the List; can be replaced with strings.add(string) if the strings are being sequentially added
CONSIDER THIS:
public class Test {
public Test() {
}
public static void main(String[] args) {
// GenericType<Integer> intObj;//creates a generic type for integers
//String type
GenericType<String> strObj=new GenericType<String>("My data");
System.out.println("Value is " +strObj.getValue());
}
}
class GenericType<GT>{
GT obT;
GenericType(GT o){
obT=o;
}
GT getValue(){
return obT;
}
void showType(){
System.out.println("Type of GT is " +obT.getClass().getName());
}
}
GT is the name of a type parameter. This name is used as a placeholder for the actual type that will be passed to GenericType when an object is created. Thus, GT is used within GenericType whenever the type parameter is needed. Notice that GT is contained within
< >. This syntax can be generalized. Whenever a type parameter is being declared, it is specified within angle brackets. Because Gen uses a type parameter, Gen is a generic class, which is also called a parameterized type.
as mentioned above JAVA provide you with advanced generic classes such as ArrayList, Vectors, Hashmaps to cater for such scenarios .
previous thread similar: How to create new variable in java dynamically
Variable names do not have data types. They are merely references. They are not a String, they are not an int, they are just names. You can't dynamically declare a variable with a name derived from the name of another variable, Java does not work this way.
Java does not work this way. Other languages do but Java isn't one of them. You can't dynamically manipulate the names of variables because they are fixed at compile time. However, in some interpreted scripting languages such a thing is possible.
To be more accurate if they are fixed to be anything at all they are fixed at compile time. If java is not compiled in debug mode the names of the variables cease to be at all. They just become addresses of memory locations.
See this for details: Can I get information about the local variables using Java reflection?
Firstly variables can be categorized into two. primitives (standard ) types such as int, float,double, char,boolean, byte... and non-primitives(user defined)types such as String, Integer, Float, Double. String type fall under non primitive , its a class provided by java.lang Api such that when you create a string variable you are indeed creating an object EX String str; str is an object it can as well be declared as String str=new String();
hence the string class consist of helper methods that may help to achieve your objective, you can as well use concatenation/joining of strings as follows:
class Demo{
String str;
static int i;
JButton but=new JButton("click me!");
.....
public static void actionPeaformed(ActionEvent e){
Object source=e.getSource();
str="msg";
if(source==but){
String newStr;
newStr=str+i;
System.out.println(newStr);
}
}
}
where str may contain some message/text eg from label/elsewhere for every click

java: ArrayList() method returning a result : if passing argument or without passing it

I want to write the method listCopies() that returns in an ArrayList all copies of a written work in a given language(eg : english); if no language is given (empty string), all copies of the library will be returned (in all languages) .
This is the code i have developed but it doesnt work cause in the main(String[] args) {...} it calls 2 times this method , one with the argument passed and in the second without an argument :
public ArrayList<Exemplary> listCopies(String l){
ArrayList <Exemplary> tmp = new ArrayList<Exemplary>();
for( int i = 0 ; i < copies.size(); i++){
if(copies.get(i).getWrittenWork().getLanguage().equals(language)){
tmp.add(Ex);
}
}
return (tmp);}
I want to rewrite this code in a way that with or without argument (String lang) > it returns the array tmp .
There's a multitude of problems with your code:
lang is used on the first line, but further on you use language
Exemplary is used on the first line, but on the 2nd you use Exemplairy
the method doesn't have a closing } at the end
you don't have code that deals with an empty language
the loop should be rewritten as an enhanced for loop
the interface List should be used instead of the class ArrayList where possible

Why is String[] args not initialized for it to be used like other String Arrays?

I'm learning Java and I was wondering, how String args[](main's argument) works. For other string arrays defined in a method, they need to be initialized with a fixed dimension for them to be used.
For example,For entering 10 or less elements in a string, I need to type String a = new String[10];
However, if I just type String a; and then type a[0] = "Word;", I get a "variable a might not have been initialized" error.
However, for String args[], I don't need to type String[] args = new args[]. Why is it so? Also, is it possible to create a string with infinite size like String args[]? (Sorry if I wasn't clear)
For other string arrays defined in a method, they need to be initialized with a fixed dimension for them to be used.
Well, that is what happens in case of String... argument of the main method. It gets initialized with the fixed number of arguments you pass as command line args. But after that, you can't add anything to the array, as the size is now fixed. If you don't pass any argument, it's length will be 0.
Note that the argument type is actually a varargs, and not a String[], although, internally the former is converted to the later anyways. The benefit you get with varargs is, you can pass variable number of arguments without explicitly creating an array.
Also, is it possible to create a string with infinite size like String args[]?
No the size of array is not unlimited. Since the type of args.length is an int. The maximum number of elements logically can be 2 ^ 32 - 1. But actually it's not even that. Memory would probably overflow much before than that.
Also note that, since we are talking about method formal parameter, there is still a restriction of maximum method size. As per JVM, the maximum size of method is restricted to 65536 bytes.
For Example:
public static void test(String... names) {
System.out.println("Names array length: " + names.length);
names[names.length] = "xyz"; // This would fail as expected.
names = new String[10]; // this however you can do. Re-assign a new array to names
}
public static void main(String... args) {
test("a", "b", "c"); // pass 3 arguments
test("a", "b"); // pass 2 arguments
}
It's only an information, that the parameter is of type String[], so it's a table of Strings.
It is a type, not any kind of initialization.
The JVM is setting up the String[] argument for you prior to passing control to your main(), sort of like this:
class InternalThingYouDoNotSee {
String[] args = build args[] from command line
Class.forName("YourClass").newInstance().getDeclaredMethod("main").invoke(args);
}
class YourClass {
public static void main(String[] args) {
/....
}
}

Variable Arguments of Object passing in array inconsistency

I wrote a function that would take variable arguments as object.
When I passed in an array of ints of size 1 eg {9}, it treated args[0] as and int array[] than an int so the valueOf did not produce 9.
But If passed in and array of 2 or more ints eg {9,11} then it treated args[0] as 9 and args[1] as 11.
Why does it behave differently.
Note it is being written for Android.
protected String[] whereArgs(Object...args) {
String[] argsStrings = new String[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof String){
argsStrings[i] = (String)args[i];
} else {
argsStrings[i] = String.valueOf(args[i]);
}
}
return argsStrings;
}
EDIT Just had a look again I was actually passing them differently in the two ints scenario, one by one and not in an array, sorry.
Why doesn't it split the method(Object...args) into an array of objects when I pass in an array of ints, like what happens with method(int...args)
So now to get the string value I have to individually cast the type of array eg. for int[], double[]
if (args[0] instanceof int[]){
argsStrings[0] = String.valueOf(((int[])args[0])[0]);
Is there a way to write it for any type of object as this causes a crash
argsStrings[0] = String.valueOf(((Object[])args[0])[0]);
java.lang.ClassCastException: int[] cannot be cast to java.lang.Object[]
If you want to pass an array and treat each item as a separate item of the 'args' parameter of your method.. you need to cast your array to an Object[]. e.g: If you pass in your array of integers like below it will do what you want.
whereArgs((Object[])(new Integer[]{1, 2}))
The reason for this is when the source is compiled var-arg methods are actually replaced by an array. all places where the method is being called is converted to an array. If you want to pass an array so that each item becomes a separate argument.. then you need to use the correct array type. in your scenario this will be Object[]. This lets the compiler know that it can leave the method call as it is (without putting the arguments inside a new object[])

Categories