I am migratimg an old visual basic application to Android and as I progressed I ran into some problems i can't solve. (I'm new to java)
In VB there is something called Dictionary and after googling the equivalent in java I come to the conclusion the thing to use is HashMap.
I need to create a HashMap with a string as key and an int[] as object:
HashMap<String, int[]> hm
So far, so good. I learned that after creating my int[] I set the HashMap the following way...
int[] intArray = new int[23];
hm.put("myRandomString", intarray);
Now to the problem, how can I change the value on position x in my intArray?
I know I will use the key to find the intArray but anything I try give me an error.
Simple:
String someKey = "myRandomString";
int[] arrayFromMap = hm.get(someKey);
if (arrayFromMap != null) {
arrayFromMap[x] = y;
Beyond that, you could/should use methods such as:
if (hm.contains(someKey))
or
if (arrayFromMap.length > x)
to check for all the possible things that could go wrong here. Also pay attention to details such as:
int[] oneArray = { 1, 2 , 3};
hm.put("a", oneArray);
hm.put("b", oneArray);
which adds the same array using two different keys. When you know do get("a") and manipulate the corresponding array, the value for "b" changes, too!
You first have to get() the array:
int[] arrToBeModified = hm.get("myRandomString");
arrToBeModified[0] = 123; // Do your modifications here.
Related
Is it possible to create a List of arrays(with fixed size) in Java?
I have tried these methods and they both give me a syntax error:
List<int[]> failedParameters = new ArrayList<int[3]>();
List<int[]> failedParameters = new ArrayList<new int[3]>();
What am I doing wrong?
No, you can't specify the array length as a Java type. However, you can wrap arrays in your own type. I'll let you decide if that is really practical (in case you have dozens of array lengths that you want to support):
class Int3 {
// Use final to indicate that the array length will remain unchanged
final int[] array = new int[3];
}
List<Int3> failedParameters = new ArrayList<Int3>();
Of course, if you go this far, why not just create an int-tuple of degree 3?
class Int3 {
int v1;
int v2;
int v3;
}
List<Int3> failedParameters = new ArrayList<Int3>();
You can use this method. It will not allow you to change the collection size (no add()/remove() operations).
List<> unmodiffableList = Collections.unmodifiableList(oListeRet);
In JavaScript, I can write code like this:
var a = new Array();
a[2] = 'a';
a[20] = 'b';
and this would not work on Java, the point is I don't want to specific the exact length for it.
How could I keep this happy style when writing java?
If you don't want to specific length you can use List like this:
List<Character> list = new ArrayList<>();
list.add('a');
list.add('b');
You cannot. Java is to Javascript as ham is to hamster. There is no reason to believe they have the same syntax.
If you want a sparse array, use a Map:
final Map<Integer, Character> a = new LinkedHashMap<>();
a.put(2, 'a');
a.put(20, 'b');
When you want an array of characters you can do it like this:
char[] array = new char[30];
array[2] = 'a';
array[20] = 'b';
Java and JavaScript are two deferent languages. you can't do same thing in both
In Java you can write
char[] arr=new char[2];
arr[0]='a';
arr[1]='b';
If you don't want to specific the length, you can use List in Java
List<Character> list=new ArrayList<>();
list.add('a');
list.add('b');
As others already pointed out: Java and JavaScript are two different things. For containers with variable size there is the Java collections framework.
But wich to choose? That depends on what you need. From your question I can imagine two cases:
a variable sized, indexed container:
basically an array-like list. In Java there's besides other list implementations the ArrayList used as follows:
List<Character> myList = new ArrayList<Character>();
// insert element at the end of the list
myList.add('a');
// insert element at specific position in list
myList.add(1, 'b');
// this will fail, because there's no element at position 2!!!
myList.add(3, 'c')
a container for mappings from integer to character:
In java there's lots of map implementations, I propose the HashMap, used like this:
Map<Integer,Character> myMap = new HashMap<Integer,Character>();
// insert mappings int -> char
myMap.put(0, 'a');
myMap.put(1, 'b');
myMap.put(20, 'c');
Each Container serves a different purpose. I advise reading the Java collections tutorial to be able to choose the best fitting one. Also take a look at tucuxi's answer, as he presented a solution wich simulates the desired beahviour but consider that (as he said himself) this is not the java way of doing things!
You can always write your own. You will not get the syntax, but most of the flavor will still be there.
Note that, efficiency-wise, this is a terrible idea. You can write much better code by learning "the Java way" of doing things. This is true of all languages: programming against the grain of the language is sure to cause you pain.
But here is the code:
class MyArray<T> extends ArrayList<T> {
public MyArray<T>() { super(); }
public void add(int i, T value) {
if (size() < i) {
ensureCapacity(i+1); // grow at most once instead of multiple times
while (size() < i)) {
add(null); // extend with a null object
}
add(value);
} else {
add(i, value);
}
}
}
Now you can compare a garden-variety ArrayList with an instance of MyArray:
ArrayList<Character> a = new ArrayList<>();
MyArray<Character> b = new MyArray<>()
a.add(10, 'X'); // IndexOutOfBoundsException, size is 0
b.add(10, 'X'); // no exception - you get [10 x null, 'X']
b.get(10); // returns 'X'
Bear in mind that JavaScript arrays can be indexed by arbitrary objects and not only integers -- but that the JavaScript VM tries to use numerically-indexed arrays if at all possible. For arbitrary indexing, you would need to use a Java HashMap:
class MyArray2<T> extends HashMap<Object, T> {
public MyArray2<T>() { super(); }
public void add(Object o, T value) { set(o, value); }
}
You would then use as:
MyArray2<Character> c = new MyArray2<>()
c.add("anything", '?');
c.get("anything"); // returns '?'
It depends, if you are going to use an array of a fixed size you can use:
char myarray[]=new char[50];
myarray[2]='a';
myarray[20]='b';
If you are going to change the size of the array dynamically you can use a Collection like an ArrayList (look at the doc) and insert chars in the positions you want
like this
char arr[]=new char[30]; //declares an array which can hold 30 characters
arr[2]='a';
arr[20]='b';
but if you don't want to specify the length,than arraylist is something which will help you to accomplish your task because array's size is always fixed in Java
So, I'm trying to s a list of documents that contain a term and then enter the corresponding document_id and the term frequency into an array (of size 2). I then add this entry array into a List, so that the final List contains an all the entries. However, because the entry is passed by reference into the List, I have no idea how to accomplish this, since it rewrites itself every time. And due to the size of the data, my program runs out of memory if I try to declare a new int[] entry within the while loop. Any ideas on how to get pass this? I'm a but rusty on my Java. Thanks.
List<int[]> occurenceIndex = new ArrayList<>();
int[] entry = new int[2];
while (matchedDocs.next())
{
entry[0] = (matchedDocs.doc()); // Adds document id
entry[1] = (matchedDocs.freq()); // Adds term weight
occurenceIndex.add(entry);
}
Try to create a new object of the int array inside the loop.
List<int[]> occurenceIndex = new ArrayList<>();
while (matchedDocs.next())
{
int[] entry = new int[2];
entry[0] = (matchedDocs.doc()); // Adds document id
entry[1] = (matchedDocs.freq()); // Adds term weight
occurenceIndex.add(entry);
}
You have to put int[] entry = new int[2]; into the while loop
does it need to be an int, what about byte or short? if this isn't possible then the program needs to be re-factored as there is no way to store the arrays like this using the same array instance. – Neil Locketz 1 min ago edit
Consider using HashMap to store records.
Map<Integer, Integer> occurenceIdx = new HashMap<Integer, Integer>();
while(matchedDocs.next())
occurenceIdx.put(matchedDocs.doc(), matchedDocs.freq());
That's all the code you need to create the map. To retrieve value based on doc ID
docFreq = occurenceIdx.get(docId);
Please note that this will work ONLY if you have unique doc IDs. If not, you will have to improvise on this solution. I would probably make my map a HashMap<Integer, List<Integer>> to support multiple instances of docID
I was wondering if it is possible to convert an Object into something else.
I have a Object which contains a series of numbers in a random order such as: 3, 4, 2, 5, 1 and wondering if I am able to turn it into an int[] or select certain elements from it, as in a number from the sequence?
EDIT:
so some of the code i have is:
//This contains all the different combinations of the numbers
ArrayList routePop4 = new ArrayList();
//This picks out the first one, just as a test
Object test = routePop4.get(0);
But the idea is that I want to loop through each element of test.
An Object cannot "contain a series of numbers". However many subclasses of Object, such as all of the Collections can "contain a series of numbers", and they come with a toArray() method to turn the contents of the collection into an array.
If you have a collection, but only have access to it as an Object, you need to cast it before you can work with it properly:
ArrayList<Integer> list = (ArrayList<Integer>)test;
Integer[] arr = list.toArray(new Integer[]{});
It's fairly rare in day-to-day Java to actually be working with variables cast as Object, if you are, it should be a red flag that you may be doing something wrong. You can use generics to allow objects that contain other objects to do so generically, like so:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1); // Can only add integers, list.add("a string") would fail at compile time
int n = list.get(0); // no need to cast, we know list only contains Integers
If you aren't using a Collection, you'll presumably need to roll your own, as Luke Taylor's answer suggests. That said, you'll get better answers if you can provide more information, the current text of your question doesn't make sense in a Java context.
After seeing your edit, I recommend taking advantage of generics.
When you declare an ArrayList you can indicate what kind of objects it's going to contain.
For example, if you know your ArrayList will contain Strings, you would do this:
List<String> myList = new ArrayList<String>();
If each element of your list is an array of Integers, you would do this:
List<Integer[]> listOfIntegerArrays = new ArrayList<Integer[]>();
Then you could get any element from your list and assign it to an Integer array like this:
Integer[] integerArray = listOfIntegerArrays.get(0);
Then you could iterate over every Integer in the list like this:
for (Integer loopInteger : integerArray) {
System.out.println("The value: " + loopInteger);
}
Some more reading on generics:
http://thegreyblog.blogspot.com/2011/03/java-generics-tutorial-part-i-basics.html
http://docs.oracle.com/javase/tutorial/java/generics/
You could do something like this:
int[] numbersFromObject = new int[yourObject.getAmountOfNumbers()];
// Initialize array with numbers from array
for(int i = 0; i < yourObject.getAmountOfNumbers(); i++) {
numbersFromObject[i] = yourObject.getNumber(i);
}
I'm not sure what methods your object contains, yet I'm sure you'll be able to adjust to the following mentioned above.
I hope this helps.
Let's say I needed to make a series of String[] objects.
I know that if i wanted to make a string array called "test" to hold 3 Strings I could do
String[] test = new String[3];
But let's say I needed to make a series of these arrays and I wanted them to be named, 1,2, 3, 4, 5... etc. For however many I needed and I didn't know how many I'd need.
How do I achieve a similar effect to this:
for (int k=0; k=5; k++){
String[] k = new String[3];
}
Which would created 5 string arrays named 1 through 5. Basically I want to be able to create array objects with a name detemined by some other function. Why can't I seem to do this? Am I just being stupid?
There aren't any "variable variables" (that is variables with variable names) in Java, but you can create Maps or Arrays to deal with your particular issue. When you encounter an issue that makes you think "I need my variables to change names dynamically" you should try and think "associative array". In Java, you get associative arrays using Maps.
That is, you can keep a List of your arrays, something like:
List<String[]> kList = new ArrayList<String[]>();
for(int k = 0; k < 5; k++){
kList.add(new String[3]);
}
Or perhaps a little closer to what you're after, you can use a Map:
Map<Integer,String[]> kMap = new HashMap<Integer,String[]>();
for(int k = 0; k < 5; k++){
kMap.put(k, new String[3]);
}
// access using kMap.get(0) etc..
Others have already provided great answers, but just to cover all bases, Java does have array of arrays.
String[][] k = new String[5][3];
k[2][1] = "Hi!";
Now you don't have 5 variables named k1, k2, k3, k4, k5, each being a String[3]...
...but you do have an array of String[], k[0], k[1], k[2], k[3], k[4], each being a String[3].
The closest you will get in Java is:
Map<String, String[]> map = new HashMap<String, String[]>();
for (int k=0; k=5; k++){
map.put(Integer.toString(k), new String[3]);
}
// now map.get("3") will get the string array named "3".
Note that "3" is not a variable, but in conjunction with the map object it works like one ... sort of.
What you want to do is called metaprogramming - programming a program, which Java does not support (it allows metadata only through annotations). However, for such an easy use case, you can create a method which will take an int and return the string array you wanted, e.g. by acccessing the array of arrays. If you wanted some more complex naming convention, consider swtich statement for few values and map for more values. For fixed number of values with custom names define an Enum, which can be passed as an argument.