I want to pass two arrays of Strings into one string varsargs.
ie.
public void doSomething(String... ){
}
public void test(){
String[] arrayOne = ...
String[] arrayTwo = ...
doSomething(arrayOne, arrayTwo); //Doesn't work but just for an example
}
Is the best way to just concat the two arrays or is there a better way of doing this?
Sadly not possible in java as there is no spread operator (like in Kotlin, Ecmascript 6). You have to work your way around this by creating an intermediate array:
String[] arrayThree = new String[arrayOne.length + arrayTwo.length];
System.arraycopy(arrayOne, 0, arrayThree, 0, arrayOne.length);
System.arraycopy(arrayTwo, 0, arrayThree, arrayOne.length, arrayTwo.length);
doSomething(arrayThree);
Or using Streams:
String[] arrayThree = Stream.concat(Arrays.stream(arrayOne), Arrays.stream(arrayTwo))
.toArray(String[]::new);
doSomething(arrayThree);
As said, this is possible in kotlin and can be done like this:
val arrayOne: Array<String> = ...
val arrayTwo: Array<String> = ...
doSomething(*arrayOne, *arrayTwo)
or even in javascript:
const arrayOne = ...
const arrayTwo = ...
doSomething([...arrayOne, ...arrayTwo]);
This is because a vararg has to be the last parameter in a function. Here is an extract from Oracle documentation:
https://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html
The three periods after the final parameter's type indicate that the final argument may be passed as an array or as a sequence of arguments. Varargs can be used only in the final argument position
String... is replaced by String[], so you can't pass two array in one function expecting a vararg.
You would have to merge your arrays into one.
You can only pass multiple array in the varargs if they all are of same type
public static void doSomething(String[] ...args){
}
public static void test(){
String[] arrayOne = {};
String[] arrayTwo = {};
doSomething(arrayOne, arrayTwo); //Doesn't work but just for an example
}
You can merge two arrays with this instruction:
import org.apache.commons.lang3;
// ...
String[] both = (String[])ArrayUtils.addAll(arrayOne , arrayTwo);
doSomething(both);
// ...
or you can pass both arrays.
public void doSomething(String[] pArrayOne, String[] pArrayTwo ){
}
public void test(){
String[] arrayOne = ...
String[] arrayTwo = ...
doSomething(arrayOne, arrayTwo);
}
Related
Cannot create nested ArrayList from Array in Java
I am trying to create a nested list from an array.
But I have a problem while converting Object to String:
Object[] array = new Object[] {
new String[] {"add, hack"},
new String[] {"add, hackerrank"},
new String[] {"find, hac"},
new String[] {"find, hak"}
};
List<List<String>> list = Arrays.asList(Arrays.asList((array.toString())));
So, how can I convert it properly?
Here is the method that reserves the List<List<String>>:
public static List<Integer> contacts(List<List<String>> queries) {
for (List<String> query : queries) {
String operation = query.get(0); // --> gives "add, hack" (I expect "add")
String word = query.get(1);
}
}
Every array inside the source array in your code like new String[] {"add, hack"} is treated as Object - that's all the compiler knows about it because array has been declared as Object[] (i.e. array of objects, not array of arrays objects, or array of arrays of strings).
Arrays.asList(array.toString()) - creates a list with a single element of type String. And when you invoke toString() on an array of any type, you will obtain a string containing the array's type and hash-based sequence of symbols after the at-sign #. In order to get a string representation of the array contents, you need to use static method toString() of the Arrays class.
This way you can approach the problem of casting an array of Object type
public static void main(String[] args) {
Object[][] array = new Object[][]{
new String[] {"add, hack"},
new String[] {"add, hackerrank"},
new String[] {"find, hac"},
{"find, hak"} // you can omit new String[] when assigning array while at the same time with initialization
};
List<List<String>> list = arraysToList(array, String.class);
System.out.println(list);
}
Generic method for casting, that expects a Class object as a parameter:
public static <T> List<List<T>> arraysToList(Object[][] array, Class<T> clazz) {
return Stream.of(array)
.map(arr -> Stream.of(arr).map(clazz::cast).toList())
.collect(Collectors.toList());
}
Output
[[add, hack], [add, hackerrank], [find, hac], [find, hak]]
Your Question is unclear as to your goal. Perhaps you want to generate text in a specific format. If so, add a method to the record class Query that returns a String object in your desired format.
If you need to split a single string containing non-alphabetic symbols into separate words, you can make use of the split() method:
str.split("[^\\p{Alpha}]+"); // returns an array of strings comprised of alphabetic symbols only
Use objects, not lists of arrays
The other Answers seem to be correct about your various problems. I will look at the bigger picture… Your design approach has ignored the the best feature of Java: object-oriented programming.
Your query pieces should be packaged as a class, a record.
record Query ( String verb , String noun ) {}
Apparently you are starting with a comma-separated string as inputs. So add a static factory method to parse each input.
record Query ( String verb , String noun ) {
// Factory method to instantiate `Query` object by parsing input string containing a pair of comma-separated values.
public static Query parse( final String input ) {
String[] parts = input.split( ", " ) ;
return new Query ( parts[0] , parts[1] ) ;
}
}
Skip the arrays, and use List or Set for their convenience.
List< Query > queries =
List.of(
Query.parse( "add, hack" ) , // Instantiates a `Query` object.
Query.parse( "add, hackerrank" ) ,
Query.parse( "find, hac" ) ,
Query.parse( "find, hak" )
)
;
Generating text
Report contents.
System.out.println( "queries = " + queries );
queries = [Query[verb=add, noun=hack], Query[verb=add, noun=hackerrank], Query[verb=find, noun=hac], Query[verb=find, noun=hak]]
Your Question is not clear as to its end goal. If your goal is to generate text in a particular format, add a method to your class. Here we add a method called report.
String report ( ) { return String.format( "{ %s, %s }" , this.verb , this.noun ); }
To use that report method, loop your objects, generating text for each.
queries.forEach( query -> System.out.println( query.report() ) );
{ add, hack }
{ add, hackerrank }
{ find, hac }
{ find, hak }
Caveat: In real work, we would do more to verify and validate. For example we would validate our input data to make sure the input string is non-null, non-blank, and composed of two parts. I omitted such code to keep the demo short and on-point.
One more solution assuming you want to start from Object[] array - first transforms to list of String[] using casting and then maps every String[] to List:
List<String[]> arrList = new ArrayList<>();
for (Object o : array)
arrList.add((String[]) o);
List<List<String>> strList = arrList.stream()
.map(Arrays::asList)
.collect(Collectors.toList());
In order to be an "array of arrays" it would need to be a 2-dimensional array:
String[][] arrays = new String[][] {new String[] {"add, hack"}, ...}
Then you could convert each array inside the array into an item in the list
List<List<String>> list = new ArrayList<>();
for (String[] array : arrays) {
list.add(Arrays.asList(array));
}
You can stream the array and then collect to a List:
Object[] array = new Object[] {
new String[] {"add, hack"},
new String[] {"add, hackerrank"},
new String[] {"find, hac"},
new String[] {"find, hak"}};
List<List<String>> list = Arrays.stream(array)
.map(String[].class::cast)
.map(arr -> arr[0].split(", "))
.map(Arrays::asList)
.collect(Collectors.toList());
System.out.println(list);
Output:
[[add, hack], [add, hackerrank], [find, hac], [find, hak]]
With JDK 16+ you can do:
List<List<String>> list = Arrays.stream(array)
.map(String[].class::cast)
.map(arr -> arr[0].split(", "))
.map(Arrays::asList)
.toList();
I want to sort an array based on another array with different values.
Consider the following:
Reference Array: {"A","B","C"}
Obtained Array1: {"C","A","B"}
Obtained Array2: {"cc","aa","bb"}
Obtained Array3: {"123","asrd","sdhg"}
values corresponding to
A -> aa and asrd
B -> bb and sdhg
C -> cc and 123
I want to sort my obtained array 1, 2 and 3 in the order specified by my reference array.
Expected Result:
Obtained Array after sorting: {"A","B","C"}
Obtained Array2 after sorting: {"aa","bb","cc"}
Obtained Array3 after sorting: {"asrd","sdhg","123"}
PS: The reference array elements order can be anything ([A,B,C] or [C,B,A] etc). Obtained arrays 2 and 3 should be sorted accordingly.
I know how to sort Obtained Array 1 in the order of my reference array. I tried a logic to sort obtained arrays 2 and 3 but the result i get is wrong
String[] referenceArray = new String[] { "A", "B", "C" };
String[] obtainedArray1 = new String[] { "C", "A", "B" };
String[] obtainedArray2 = new String[] { "cc", "aa", "bb" };
String[] obtainedArray3 = new String[] { "123", "asrd", "sdhg" };
final List<String> referenceArrayList= Arrays.asList(referenceArray);
ArrayList<String> obtainedArray1_List= new ArrayList<String>(Arrays.asList(obtainedArray1));
ArrayList<String> obtainedArray2_List= new ArrayList<String>(Arrays.asList(obtainedArray2));
ArrayList<String> obtainedArray3_List= new ArrayList<String>(Arrays.asList(obtainedArray3));
// Sorting ObtainedArray1_List - This works Fine
Collections.sort(obtainedArray1_List, Comparator.comparing(s -> referenceArrayList.indexOf(s)));
//Sorting obtainedArray2_List - Not Working
Collections.sort(obtainedArray2_List, Comparator.comparing(s -> referenceArrayList.indexOf(obtainedArray1[obtainedArray2_List.indexOf(s)])));
The result of obtainedArray2_List after sorting: ["aa","cc","bb"]
Expected Result is ["aa","bb","cc"]
As JB Nizet already said, you're making your life complicated. You have three separate arrays, while their contents are related. You're saying that A, aa and asrd belong together, as well as B, bb and sdhg, and C, cc and 123.
These can be thought of three properties of a single object. That's the point of object-orientation. You should define a class which represents these three properties:
public class Holder {
private String letter;
private String lower;
private String text;
public Holder(String letter, String lower, String text) {
this.letter = letter;
this.lower = lower;
this.text = text;
}
public String getLetter() {
return this.letter;
}
#Override
public String toString() {
return String.format("Holder(letter=%s, lower=%s, text=%s)",
this.letter, this.lower, this.text);
}
}
Your three arrays should never exist in the first place, but instead being an array or collection with Holder objects. For convenience, here is a transformation to a List<Holder>.
List<Holder> holders = IntStream.range(0, obtainedArray1.length)
.mapToObj(i -> new Holder(obtainedArray1[i], obtainedArray2[i], obtainedArray3[i]))
.collect(Collectors.toList());
Now you can simply sort collect a new, sorted list, instead of three separate sorted arrays.
List<String> referenceList = Arrays.asList("A", "B", "C");
List<Holder> sorted = holders.stream()
.sorted(Comparator.comparing(t -> referenceList.indexOf(t.letter)))
.collect(Collectors.toList());
I have a series of String[] arrays which are list of words. Something like:
String[] ListOne = new String[100];
String[] ListTwo = new String[100];
/*And so on with other lists */
ListOne[0] = "word00";
ListOne[1] = "word01";
/*And so on till*/
ListLast[99] = "word 99 from last list";
Now I want a function for each list that, given a number returns the corresponding element (word):
public String GetFromListOne(int key) { return ListOne[key];}
Is there a way to avoid manually writing each of this getter functions?
In PHP, for example, I would just use the magic method __call,
or pass as an argument with the list name and reference it dynamically.
Is there a way to do something similar in Java?
Or an alternative strategy to achieve the same result?
You should look into inheritance.
What you basically must do is define an interface (or extend a List class)
public interface ListTest{
//**Gets keys from lists*//
GetFromListOne(int key);
}
then
public class Listone implements ListTest{
/** methods **//
GetFromListOne(int key);
/** methods **//
}
Have fun extending
http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html
You could use a 2 dimensional array, or a list of arrays and have your function take 2 parameters. One for the array that you want and the other for the element in the array.
2 dimensional array:
String[][] ListN = new String[100,100];
String getFromList(int n, int key) {
return ListN[n][key];
}
Or list of arrays:
List<String[]> listOfArrays = new ArrayList<String[]>();
listOfArrays.add(new String[100]);
listOfArrays.add(new String[100]);
String getFromList(int n, int key) {
return listOfArrays.get(n)[key];
}
Could you have a function that takes as input the key and the list number:
public String GetFromListOne(int list, int key) {
switch(list):
case 1:
return ListOne[key];
break;
case 2:
return ListTwo[key];
break;
...
}
or even better make an array of arrays:
String[][] ListOfLists = new String[10];
ListOfLists[0] = new String[100];
...
public String GetFromList(int list, int key) {
return ListOfLists[list][key];
}
Otherwise I don't know of a function to override like __call
String[] ListFour=new String[100];
String[] ListTwentyThree=new String[100];
String[] ListNine=new String[100];
String[] ListOne=new String[100];
Hashtable<Integer,String[]> yourlist=new Hashtable<Integer,String[]>();
yourlist.put(4, ListFour);
yourlist.put(23, ListTwentyThree);
yourlist.put(9, ListNine);
yourlist.put(1, ListOne);
System.out.println(yourlist.get(4)[5]);//fifth string in ListFour
System.out.println(yourlist.get(23)[51]);//fifty first string in List23
System.out.println(yourlist.get(9)[1]);//first stringin ListNine
another version:
Hashtable<Object,String[]> yourlist=new Hashtable<Object,String[]>();
yourlist.put("two multiplied by two", ListFour);
yourlist.put(23, ListTwentyThree);
yourlist.put(0.03, ListNine);
yourlist.put(true, ListOne);
System.out.println(yourlist.get("two multiplied by two")[5]);//fifth string in ListFour
System.out.println(yourlist.get(23)[51]);//fifty first string in List23
System.out.println(yourlist.get(true)[1]);//first stringin ListNine
Based in the __call PHP method, you can achieve this implementing a method that receives the list and the index, and using generics you can get something like this.
public class Utility {
public <T> T getElementFromArray(T[] array, int index) {
if (index >= array.length || index < 0) return null;
return array[index];
}
}
The pitfall of this method is that can't be used for primitive array holders, like int[]. The solution for these cases would be using the wrapper classes for primitive types.
public static void main(String[] args) {
Utility u = new Utility();
String[] ss = new String[2];
ss[0] = "Hello";
ss[1] = "world!";
System.out.println(u.getElementFromArray(ss, 0));
System.out.println(u.getElementFromArray(ss, 1));
int[] ii = new int[2];
ii[0] = 5;
System.out.println(u.getElementFromArray(ii, 0)); //compile error
//Solution: use wrapper classes
Integer[] ii2 = new Integer[2];
ii2[0] = 5;
System.out.println(u.getElementFromArray(ii2, 0));
}
Try this code
List<String[]> lists = new ArrayList<String[]>();
public String getFromLists(int key) {
List<String> res = new ArrayList<String>();
for (String[] s: lists){
res.add(s[key]);
}
return res.get(key);
}
or better
public String getFromLists(int key) {
return lists.get(key)[key];
}
Error
% javac StringTest.java
StringTest.java:4: variable errorSoon might not have been initialized
errorSoon[0] = "Error, why?";
Code
public class StringTest {
public static void main(String[] args) {
String[] errorSoon;
errorSoon[0] = "Error, why?";
}
}
You need to initialize errorSoon, as indicated by the error message, you have only declared it.
String[] errorSoon; // <--declared statement
String[] errorSoon = new String[100]; // <--initialized statement
You need to initialize the array so it can allocate the correct memory storage for the String elements before you can start setting the index.
If you only declare the array (as you did) there is no memory allocated for the String elements, but only a reference handle to errorSoon, and will throw an error when you try to initialize a variable at any index.
As a side note, you could also initialize the String array inside braces, { } as so,
String[] errorSoon = {"Hello", "World"};
which is equivalent to
String[] errorSoon = new String[2];
errorSoon[0] = "Hello";
errorSoon[1] = "World";
String[] args = new String[]{"firstarg", "secondarg", "thirdarg"};
String[] errorSoon = { "foo", "bar" };
-- or --
String[] errorSoon = new String[2];
errorSoon[0] = "foo";
errorSoon[1] = "bar";
In Java 8 we can also make use of streams e.g.
String[] strings = Stream.of("First", "Second", "Third").toArray(String[]::new);
In case we already have a list of strings (stringList) then we can collect into string array as:
String[] strings = stringList.stream().toArray(String[]::new);
I believe you just migrated from C++, Well in java you have to initialize a data type(other then primitive types and String is not a considered as a primitive type in java ) to use them as according to their specifications if you don't then its just like an empty reference variable (much like a pointer in the context of C++).
public class StringTest {
public static void main(String[] args) {
String[] errorSoon = new String[100];
errorSoon[0] = "Error, why?";
//another approach would be direct initialization
String[] errorsoon = {"Error , why?"};
}
}
String[] arr = {"foo", "bar"};
If you pass a string array to a method, do:
myFunc(arr);
or do:
myFunc(new String[] {"foo", "bar"});
String[] errorSoon = new String[n];
With n being how many strings it needs to hold.
You can do that in the declaration, or do it without the String[] later on, so long as it's before you try use them.
You can always write it like this
String[] errorSoon = {"Hello","World"};
For (int x=0;x<errorSoon.length;x++) // in this way u create a for loop that would like display the elements which are inside the array errorSoon.oh errorSoon.length is the same as errorSoon<2
{
System.out.println(" "+errorSoon[x]); // this will output those two words, at the top hello and world at the bottom of hello.
}
You can use below code to initialize size and set empty value to array of Strings
String[] row = new String[size];
Arrays.fill(row, "");
String Declaration:
String str;
String Initialization
String[] str=new String[3];//if we give string[2] will get Exception insted
str[0]="Tej";
str[1]="Good";
str[2]="Girl";
String str="SSN";
We can get individual character in String:
char chr=str.charAt(0);`//output will be S`
If I want to to get individual character Ascii value like this:
System.out.println((int)chr); //output:83
Now i want to convert Ascii value into Charecter/Symbol.
int n=(int)chr;
System.out.println((char)n);//output:S
String[] string=new String[60];
System.out.println(string.length);
it is initialization and getting the STRING LENGTH code in very simple way for beginners
The Java Docs for the method
String[] java.io.File.list(FilenameFilter filter)
includes this in the returns description:
The array will be empty if the directory is empty or if no names were accepted by the filter.
How do I do a similar thing and initialize a String array (or any other array for that matter) to have a length 0?
As others have said,
new String[0]
will indeed create an empty array. However, there's one nice thing about arrays - their size can't change, so you can always use the same empty array reference. So in your code, you can use:
private static final String[] EMPTY_ARRAY = new String[0];
and then just return EMPTY_ARRAY each time you need it - there's no need to create a new object each time.
String[] str = new String[0];?
String[] str = {};
But
return {};
won't work as the type information is missing.
Ok I actually found the answer but thought I would 'import' the question into SO anyway
String[] files = new String[0];
or
int[] files = new int[0];
You can use ArrayUtils.EMPTY_STRING_ARRAY from org.apache.commons.lang3
import org.apache.commons.lang3.ArrayUtils;
class Scratch {
public static void main(String[] args) {
String[] strings = ArrayUtils.EMPTY_STRING_ARRAY;
}
}
Make a function which will not return null instead return an empty array you can go through below code to understand.
public static String[] getJavaFileNameList(File inputDir) {
String[] files = inputDir.list(new FilenameFilter() {
#Override
public boolean accept(File current, String name) {
return new File(current, name).isFile() && (name.endsWith("java"));
}
});
return files == null ? new String[0] : files;
}
You can use following things-
1. String[] str = new String[0];
2. String[] str = ArrayUtils.EMPTY_STRING_ARRAY;<br>
Both are same.