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];
}
Related
I have an arrayList that contains arrays. How do I check if the arrayList contains a specified array? I used .contains method and it returns false instead of expected true.
import java.util.ArrayList;
import java.util.Arrays;
public class main {
public static void main(String[] args) {
ArrayList<String[]> action = new ArrayList<String[]>();
action.add(new String[]{"appple", "ball"});
String[] items = new String[]{"appple", "ball"};
if (action.contains(new String[]{"appple", "ball"})) {
System.out.println("Yes");
}
System.out.println(action.contains(items)); // False
}
}
As you are creating different arrays (even if the contents are the same), contains will result false.
However, if you do this:
List<String[]> action = new ArrayList<String[]>();
String[] items = new String[]{"apple","ball"};
action.add(items);
if (action.contains(items))
System.out.println("Yes");
This will print Yes.
Also, some examples of the behaviour:
String[] items = new String[]{"apple","ball"};
action.add(items);
String[] clone = items.clone();
String[] mirror = items;
action.contains(clone); // false
action.contains(mirror); // true
items[0]="horse";
System.out.println(mirror[0]); // "horse"
System.out.println(clone[0]); // "apple"
System.out.println(action.get(0)[0]); // "horse"
mirror[1]="crazy";
System.out.println(clone[1]); // "ball"
System.out.println(action.get(0)[1]); // "crazy"
System.out.println(items[1]); // "crazy"
clone[1]="yolo";
System.out.println(action.get(0)[1]); // "crazy"
System.out.println(items[1]); // "crazy"
System.out.println(mirror[1]); // "crazy"
System.out.println(action.get(0).hashCode()); //2018699554
System.out.println(items.hashCode()); //2018699554
System.out.println(clone.hashCode()); //1311053135
System.out.println(mirror.hashCode()); //2018699554
Custom "contains"
The issue here is that if you want to search for an specific array afterwards, you'd lose the references and searching an item wouldn't be possible, not even replicating the array with the same exact values.
As a workaround, you could implement your own contains method. Something like:
If you wish to get the index:
static int indexOfArray(List<String[]> list, String[] twin)
{
for (int i=0;i<list.size();i++)
if (Arrays.equals(list.get(i),twin))
return i;
return -1;
}
And then, call it like:
String[] toSearch = new String[]{"apple","ball"};
int index = indexOfArray(action, toSearch);
if (index>0)
System.out.println("Array found at index "+index);
else
System.out.println("Array not found");
If the index is bigger than -1, you can get your original array by just:
String[] myArray = action.get(index);
HashMap + identifier
An alternative would be storing the arrays into a HashMap by declaring an identifier for each array. For example:
Base64 ID
This will give the same result for the same values, as the encoded value is based on the entries, not the Object's reference.
static String getIdentifier(String[] array)
{
String all="";
for (String s : array)
all+=s;
return Base64.getEncoder().encodeToString(all.getBytes());
}
And then you could:
Map<String, String[]> arrayMap= new HashMap<>();
String[] items = new String[]{"apple","pear", "banana"}; // *[1234]
action.add(items);
arrayMap.put(getIdentifier(items), items); // id = QUJDYWFh
//....
//Directly finding the twin will fail
String[] toSearch = new String[]{"apple","pear", "banana"}; // *[1556]
System.out.println(action.contains(toSearch)); // false
//But if we get the identifier based on the values
String arrId = getIdentifier(toSearch); // id = QUJDYWFh
System.out.println(action.contains(arrayMap.get(arrId))); //true
//arrayMap.get(arrId)-> *[1234]
//.....
Name.
Choose a representative name and use it as Id
Map<String, String[]> arrayMap= new HashMap<>();
String[] items = new String[]{"apple","pear", "banana"};
action.add(items);
arrayMap.put("fruits", items);
//...
System.out.println(action.contains(arrayMap.get("fruits"))); // true
The 'contains' method compares equivalent hashCode values.
So if you make it like below*, it will pass.
public class main {
public static void main(String[] args) {
ArrayList<String[]> action = new ArrayList<String[]>();
String[] items = new String[]{"appple","ball"};
action.add(items);
System.out.println("TO STRING");
System.out.println("--"+action.get(0));
System.out.println("--"+new String[]{"apple","ball"});
System.out.println("HASHCODES");
String[] sameValues = new String[]{"apple","ball"};
System.out.println("--"+action.get(0).hashCode());
System.out.println("--"+items.hashCode());
System.out.println("--"+sameValues.hashCode());
System.out.println("CONTAINS");
System.out.println("--"+action.contains(items)); // *this
System.out.println("--"+action.contains(sameValues));
System.out.println("--"+action.contains(new String[]{"apple","ball"}));
}
}
result is:
TO STRING
--[Ljava.lang.String;#7b1d7fff
--[Ljava.lang.String;#299a06ac
HASHCODES
--1243554231
--1243554231
--2548778887
CONTAINS
--true
--false
--false
Regarding the code shown when printing the array, these don't override toString(), so you get:
getClass().getName() + '#' + Integer.toHexString(hashCode())
For example:
[Ljava.lang.String;#7b1d7fff
[ stands for single dimension array
Ljava.lang.String stands for the type
#
7b1d7fff Hex representation of the hashcode
However, if you want to compare the values, there is the following method.
public class main {
public static void main(String[] args) {
String[] items = new String[]{"apple","ball"};
ArrayList<String> action = new ArrayList<>(Arrays.asList(items));
if (action.contains("apple")) {
System.out.println("Yes");
}
}
}
You can iterate over this list and for each element, i.e. array, call Arrays.equals method to check equality of arrays until first match, or till the end of the list if none match. In this case it can return true for each element:
List<String[]> list = List.of(
new String[]{"appple", "ball"},
new String[]{"appple", "ball"});
String[] act = new String[]{"appple", "ball"};
System.out.println(list.stream()
.anyMatch(arr -> Arrays.equals(arr, act))); // true
This method internally calls String#equals method for each element of the array, i.e. String, so this code also returns true:
List<String[]> list = List.of(
new String[]{new String("appple"), new String("ball")},
new String[]{new String("appple"), new String("ball")});
String[] act = new String[]{new String("appple"), new String("ball")};
System.out.println(list.stream()
.anyMatch(arr -> Arrays.equals(arr, act))); // true
According to JavaDocs, "contains" method is using "equals" and "hashCode" methods in order to check whether an object is contained.
A leading question:
Do you know what's the implementation of "equals" for arrays?
Check it and you will probably understand your code's execution result (hint: ==).
As "Hovercraft Full Of Eels" said, a better design will be using a list of some Collection which you DO understand / control it's "equals" and "hashCode" methods.
I have an array list which when populated has a key and a value I want to know if there is a way of splitting it on repeating keys for example my current data is like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom, RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave, RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
I want it to come out more like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom]
[RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave]
[RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
Is there a way to split it on say role id or am I going about this the wrong way?
You can try by using HashMap
private static class MyItemHashMap extends HashMap {
public Item add(Item item) {
get(item).add(item);
return item;
}
public List get(Item key) {
List list = (List) get(createItemKey((Item) key));
return list == null ? createItemEntry((Item) key) : list;
}
private List createItemEntry(Item item) {
List list = new ArrayList();
put(createItemKey(item), list);
return list;
}
private Object createItemKey(Item item) {
return item.getSplitterProperty();
}
}
public static void main(String[] args) {
MyItemHashMap itemMapped = new MyItemHashMap();
List items = Arrays.asList(new Object[]{new Item("A"), new Item("B"),
new Item("C")});
for (Iterator iter = items.iterator(); iter.hasNext();) {
Item item = (Item) iter.next();
itemMapped.add(item);
}
}
If it is an ArrayList, there is no built-in function to split data like this; you will have to do it manually. If you know the number of consecutive fields that make a single structure, this shouldn't be too hard; something like this:
// 6 because there are 6 fields
for (int i = 0; i < arrayList.size(); i = i + 6) {
List thisList = arrayList.subList(i, i + 5);
// ... Now do whatever you want with thisList - it contains one structure.
}
If the number of fields can change then you'll have to do something a little more dynamic and loop through looking for a RoleID field, for example.
I'd use a HashMap to seperate the data instead of one long ArrayList ( you shouldn't have stored the data like this in the first instance )
HashMap<String,ArrayList<String>> hm = new HashMap<String,ArrayList<String>>;
// For each list:
ArrayList<String> arr = new ArrayList<String>;
arr.add("each element");
hm.put("RoleID_123.0", arr);
This way you will end up with a three dimensional structure with a key ( "RoleID..." ) pointing to its child elements.
Try this
String[] str=new String[]{"RoleID_123.0", "UserHandel_tom", "Password_12345.0", "prevPassword_null", "userCaption_thomas", "Email_tom#tom.tom", "RoleID_124.0", "UserHandel_dave", "Password_ghadf", "prevPassword_sdfsd", "userCaption_david", "Email_dave#dave.dave", "RoleID_125.0", "UserHandel_trevor", "Password_tre", "prevPassword_null", "userCaption_trev", "Email_trev#trev.trev"};
List<String> list=new ArrayList<>(Arrays.asList(str));
List<String> subList=list.subList(0,5);
You can try something similar to this
If you feel like taking a Linq-ee Libraried approach, this is about as good as it gets, and it requires use of a couple delegate objects:
import static com.google.common.collect.Collections2.filter;
import static com.google.common.collect.Collections2.transform;
//...
final List<String> yourList = //...
final int RECORD_LENGTH = 6;
Collection<String> roleIdValues = filter(yourList, new Predicate<String>() {
public boolean apply(#Nullable String input) {
return input != null && input.startsWith("RoleID");
}
});
Collection<Collection<String>> splitRecords = transform(roleIdValues, new Function<String, Collection<String>>() {
#Nullable public Collection<String> apply(#Nullable String input) {
return yourList.subList(yourList.indexOf(input), RECORD_LENGTH);
}
});
If Oracle had delivered Java 8 on time you would be able to do this in a way more slick manor. Ironically the reason you cant was provided by the same people providing the guava library
If I have two class constants:
List<String> workingList= new ArrayList<String>();
StringBuilder holder = new StringBuilder(50);
both residing within, call it class StringParser and primary method readStuff()...
public class StringParser{
public void readStuff(){
//parsing logic and adding <String> elements to
//said workingList...
}//end of method readStuff
followed by a method where I inspect the contents of workingList...
public String someReaderMethod()
{
int ind = 0;
for(int i = 0; i < workingList.size();i++)
{
if(workingList.get(i).contains(someExp))
{
workingList.remove(ind);
holder.append(workingList.get(i).toString());
}
else
{
++ind;
}
}
return holder.toString();
}
...given that StringBuilder holder now contains what workingList has removed, is there a way I can 'pass' the contents of StringBuilder to a new ArrayList?
Is there a reason why you want to use a StringBuilder? You can directly insert the values into a new ArrayList. I think you could do it in a simpler way.
List<String> discardedList = new ArrayList<String>();
public void readStuff() {}
public static List<String> someReaderMethod()
{
for(int i = 0; i < workingList.size(); i++)
{
if(workingList.get(i).contains(someExp))
{
discardedList.add(workingList.get(i));
workingList.remove(i);
}
}
return discardedList;
}
You will need a deliminator to parse string and then you can use Split method and convert String[] to ArrayList.
holder.append(tempList.get(i));
holder.append(";");//Deliminator
Now when you have to use it you need to do
String[] strings =holderString.split(";");
List<String> list = Arrays.asList(strings);
While appending your List elements to your StringBuilder object, you need to append an extra delimiter after every append..
Later on, you can split the String in StringBuilder on that delimiter, and then convert your String array thus obtained to an ArrayList..
I would like to pass a string array as a parameter to a function. Please look at the code below
String[] stringArray = {'a', 'b', 'c', 'd', 'e'};
functionFoo(stringArray);
Instead of:
functionFoo('a', 'b', 'c', 'd', 'e');
but if I do this I am getting an error stating that convert String[] into String. I would like to know if it is possible to pass the values like that or what is the correct way to do it.
How about:
public class test {
public static void someFunction(String[] strArray) {
// do something
}
public static void main(String[] args) {
String[] strArray = new String[]{"Foo","Bar","Baz"};
someFunction(strArray);
}
}
All the answers above are correct. But just note that you'll be passing the reference to the string array when you pass like this. If you make any modifications to the array in your called function, it will be reflected in the calling function also.
There is another concept called variable arguments in Java which you can look into. It basically works like this. Eg:-
String concat (String ... strings)
{
StringBuilder sb = new StringBuilder ();
for (int i = 0; i < strings.length; i++)
sb.append (strings [i]);
return sb.toString ();
}
Here we can call the function like concat(a,b,c,d) or any number of params you want.
More Info: http://today.java.net/pub/a/today/2004/04/19/varargs.html
I believe this should be the way this is done...
public static void function(String [] array){
...
}
And the calling will be done like...
public void test(){
String[] stringArray = {"a","b","c","d","e","f","g","h","t","k","k","k","l","k"};
function(stringArray);
}
look at familiar main method which takes string array as param
More than likely your method declaration is incorrect. Make sure the methods parameter is of type String array (String[]) and not simply String and that you use double quotes around your strings in the array declaration.
private String[] stringArray = {"a","b","c","d","e","f","g","h","t","k","k","k"};
public void myMethod(String[] myArray) {}
Feel free to use this how ever you like.
/*
* The extendStrArray() method will takes a number "n" and
* a String Array "strArray" and will return a new array
* containing 'n' new positions. This new returned array
* can then be assigned to a new array, or the existing
* one to "extend" it, it contain the old value in the
* new array with the addition n empty positions.
*/
private String[] extendStrArray(int n, String[] strArray){
String[] old_str_array = strArray;
String[] new_str_array = new String[(old_str_array.length + n)];
for(int i = 0; i < old_str_array.length; i++ ){
new_str_array[i] = old_str_array[i];
}//end for loop
return new_str_array;
}//end extendStrArray()
Basically I would use it like this:
String[] students = {"Tom", "Jeff", "Ashley", "Mary"};
// 4 new students enter the class so we need to extend the string array
students = extendStrArray(4, students); //this will effectively add 4 new empty positions to the "students" array.
I think you forget to register the parameter as String[]
please check the below code for more details
package FirstTestNgPackage;
import java.util.ArrayList;
import java.util.Arrays;
public class testingclass {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.out.println("Hello");
int size = 7;
String myArray[] = new String[size];
System.out.println("Enter elements of the array (Strings) :: ");
for(int i=0; i<size; i++)
{
myArray[i] = "testing"+i;
}
System.out.println(Arrays.toString(myArray));
ArrayList<String> myList = new ArrayList<String>(Arrays.asList(myArray));
System.out.println("Enter the element that is to be added:");
myArray = myList.toArray(myArray);
someFunction(myArray);
}
public static void someFunction(String[] strArray)
{
System.out.println("in function");
System.out.println("in function length"+strArray.length );
System.out.println(Arrays.toString(strArray));
}
}
just copy it and past... your code.. it will work.. and then you understand how to pass string array as a parameter ...
Thank you
I have a list like this:
List<MyObject[]> list= new LinkedList<MyObject[]>();
and on Object like this:
MyObject[][] myMatrix;
How can I assign the "list" to "myMatrix"?
I don't want to loop over the list and assign element by element to MyMatrix, but I want to assign it directly (with the oppurtune modifications) if possible.
Thanks
You could use toArray(T[]).
import java.util.*;
public class Test{
public static void main(String[] a){
List<String[]> list=new ArrayList<String[]>();
String[][] matrix=new String[list.size()][];
matrix=list.toArray(matrix);
}
}
Javadoc
The following snippet shows a solution:
// create a linked list
List<String[]> arrays = new LinkedList<String[]>();
// add some trivial test data (note: arrays with different lengths)
arrays.add(new String[]{"a", "b", "c"});
arrays.add(new String[]{"d", "e", "f", "g"});
// convert the datastructure to a 2D array
String[][] matrix = arrays.toArray(new String[0][]);
// test output of the 2D array
for (String[] s:matrix)
System.out.println(Arrays.toString(s));
Try it on ideone
Let us assume that we have a list of 'int' array.
List<int[]> list = new ArrayList();
Now to convert it into 2D array of type 'int', we use 'toArray()' method.
int result[][] = list.toArray(new int[list.size()][]);
We can generalize it further like-
List<T[]> list = new ArrayList();
T result[][] = list.toArray(new T[list.size()][]);
Here, T is the type of array.
Use toArray() or toArray(T[]) method of LinkedList.
You can do it like this:
public static void main(String[] args) {
List<Item[]> itemLists = new ArrayList<Item[]>();
itemLists.add(new Item[] {new Item("foo"), new Item("bar")});
itemLists.add(new Item[] {new Item("f"), new Item("o"), new Item("o")});
Item[][] itemMatrix = itemLists.toArray(new Item[0][0]);
for (int i = 0; i < itemMatrix.length; i++)
System.out.println(Arrays.toString(itemMatrix[i]));
}
Output is
[Item [name=foo], Item [name=bar]]
[Item [name=f], Item [name=o], Item [name=o]]
assuming that Item is as follows:
public class Item {
private String name;
public Item(String name) {
super();
this.name = name;
}
#Override
public String toString() {
return "Item [name=" + name + "]";
}
}
Converto list to array using. List.Array()
Then Use System.arraycopy to copy to the 2d array works well for me
Object[][] destination = new Object[source.size()][];
System.arraycopy(source, 0, destination, 0, source.size());