Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have a piece of code that takes in an ArrayList<String> object and eventually takes that object and adds it to a HashMap object as the key. When I print the hashmap, the key's are all null while the values are correct.
I already know I can fix the code by passing in a copy of the ArrayList<String> object and that fixes my issue (i.e. buildHash(new ArrayList<String>(key)). But why does it point to null otherwise?
HashMap<ArrayList<String>, ArrayList<String>> hash = new HashMap<>();
ArrayList<String> key = new ArrayList<String>();
for (int i = 0; i <= 9999999; i++) {
key.add(//different strings depending on the iteration);
if ( !hash.contains(key) ) {
buildHash(key);
}
key.clear();
}
private void buildHash(ArrayList<String> key) {
ArrayList<String> follows = new ArrayList<String>();
for (int index = 0; index <= 9999999; index++) {
// add stuff to follows...
}
hash.put(key, follows);
}
I thought that the value of the key would be added to the hash, and the hash's keys would point to the value it was before it was cleared by key.clear(). That way I could reuse key over and over without creating another object in memory.
I'm new to Java (and coding) so I'm probably naive, but I thought I could save memory by utilizing the mutability of ArrayLists as opposed to Lists as the number of operations and key's generated for this project are well into the millions, if not more. Is there no avoiding that? And if not, is there any other optimization I could do?
As documented, ArrayList::clear removes all elements from the list. So you are wiping out the content.
utilizing the mutability of ArrayLists
Exactly what you do not want in a key. An object used as a key in a map should never be modifiable, not in a way that affects the outcome of the hash value calculation or affects the outcome of the equals method. Would you expect to find someone in a phone book after they changed their name?
It hard for me to imagine where you would ever want to use a list as a key in a map.
As for trying to “save memory”… don’t. The last thing a new programmer should worry about is conserving RAM. Write simple code, easy to read, easy to edit. Then let the JVM do the optimizing work for you.
I suggest you not try so hard at being clever. Spend some time looking at other code. Search Stack Overflow and elsewhere to find code similar to your logic problem or the classes you are using. Then study code samples.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
The following code faces the same problem faced by G.D in this post. Basically, multiple sublists can't modify a backing list.
For example:
import java.util.Arrays;
import java.util.List;
public class TestClass{
public static void main(String[] args){
SOtest();
}
/*a test for stack overflow. Trying to find the right data structure*/
public static void SOtest(){
int[] gers = {1,3,2,4};
ArrayList<Integer> name = new ArrayList<>();
for(int i:gers)name.add(i);
List firstSL = name.subList(0,2);
List secondSL = name.subList(2,name.size());
firstSL.remove(0);
secondSL.remove(0);
System.out.println(Arrays.toString(firstSL.toArray()));
System.out.println(Arrays.toString(secondSL.toArray()));
}
}
This code will cause a ConcurrentModificationException because firstSL and secondSL both use .remove.
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1231)
at java.util.ArrayList$SubList.remove(ArrayList.java:1054)
at TestClass.SOtest(TestClass.java:26)
at TestClass.main(TestClass.java:13)
One solution to this is copying the subLists into new arrays like so:
...
ArrayList<Integer> firstSL = new ArrayList<Integer>(name.subList(0,2));
ArrayList<Integer> secondSL = new ArrayList<Integer>(name.sublist(2,name.size());
However, I'd like to avoid this solution because I need to do this operation a lot and copying takes too much time.
The subLists I'm creating will never overlap so I don't see why this is a problem.
for example I'll never have
name = [1,2,3,4]
firstSL = [1,2]
secondSL = [2,3,4]
Is there a Collection that has this behavior?
Edit:
As suggested in the comments, I'll try to elaborate. The entire behavior I need is: an ordered collection that has the above ability to be sublisted, accessed by an index, give its size and removed by an index.
I doubt this is useful, but it will be used in the MergeSort subClasses of this sorting algorithm github.com/user-name-is-taken/Merge_sort.
No. List#subList explicitly calls this sort of thing out as being "undefined" if the backing list is disturbed in any way:
The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)
If you want something like this, you'll have to engineer your own solution. What you have is a decent start, but you may want to encapsulate it in a proper object on your own.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Suppose I need to create a multi-set data structure with operations such as intersect and union of two sets. With c# or java.
In both cases I need create a copy of every object of both sets, otherwise changing one of it could break other sets.
I see one solution: specify generic type, for example
class MultiSet<T, U> where T : struct, where U : ICloneable
or something like this in java.
Are there another ways to solve this?
In both cases I need create a copy of every object of both sets, otherwise changing one of it could break other sets
If you want an intersect of two collections of objects, you will want references to those that "match" as a result, rather than copies of them. The latter makes no sense.
To check wether two objects are the same (in set 1 and set 2), just compare them in a meaningful way (i.e. overriding their hash code and compare methods).
The structure of your result collection will also depend on wether or not the objects can be equal to each other without their reference being equal. In that case, the resulting collection will need to hold two references (two for each "match"), one for each set.
As for the union, just simply create one collection that holds references to all the objects in both collections.
Complete side note
Union and intersect are data operations, and so I assume your collections will hold data. It's not the best idea to do such operations in a programming language. There are other tools that are much more up to the task, such as SQL.
Other than the recommended ICloneable? (I say the recommended way, however cloning is usually seen as bad)
I suppose if the objects are Serializable you could serialize and de-serialise as a new object.
var formatter = new BinaryFormatter();
var stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, yourObject);
stream.Seek(0, SeekOrigin.Begin);
return (YourObjectType)formatter.Deserialize(stream);
}
Add a null check and it would make a nice extension method for serialisable objects.
Once again though, cloning probably is not a good solution for your problem, but I don't know enough about your use-case to recommend anything.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
list() method
// return a string that contains all the HotelRoom objects in the HotelRoom array.
public String list()
{
}
• The list method will return a string containing all the rooms that the user entered into the system. If there are no rooms entered this method lets the user know that no cars exist.
• This method is public, returns a String value and takes no parameters.
• Firstly check that the array is not empty by using the following code:
if(myHotelIn.isEmpty())
{
System.out.println(“All rooms are available”);
}
else
{
In this method the second thing you need to do is to declare a local String variable, called list. This will hold the list of all rooms in the array and will be returned from this method.
• If the HotelRoom array is not empty (hint: use the isEmpty() method),
o write a for loop that will retrieve each room in the array and add its details (room name, room type and room price) to the list variable.
Return the list variable.
}
HEY I HAVE A PROBLEM WITH THIS PART OF JAVA APPLICATION. I HAVE GOT ASSIGNMENT TO DO BUT I AM REALLY STUCK WITH IT, I'VE DONE MOST OF THE WORK BUT THIS ONE GIVE ME A LOT OF TROUBLES. I DON'T KNOW EVEN WHERE TO START. PLEASE IF YOU CAN GIVE ME SOME TIPS WITH IT. THANKS
The first thing you should be looking into is a for each loop. This is a type of loop that goes through every single element in an array or Collection implementation. You can read up on these here.
Next, you'll need to look into the StringBuilder class, which can be read about here. This class is designed to allow efficient creation of a String object, which you will be using.
Finally, you'll need to use the append method in the StringBuilder class, to link up several String representations of each HotelRoom, probably using the toString() method.
NOTE
You'll notice I've not provided any code, because I don't think you've had a fair go at solving the issue just yet. Edit in your attempts and I'll edit in some code.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I need to store some entity object + counter of each groups entities objects.
How can I do this?
If the counter variable is not a part of the object itself, you can use Map<Object,Integer> as other answers suggest. However, keep in mind that you can use any collection or list if the counter is a part of the object data. Then you will update the counter with setters. Alternatively, updating the counter within particular constructors of various classes may also be a preferred way.
class Data
{
int counter = 0;
Data()
{
counter++;
}
}
You can use a Map
Map<Object, Integer> map = new HashMap<Object, Integer>();
Here, Object is your key and Integer is your count .
Your keys should be unique in the HashMap.
As it uses hashing, it will help in efficient retrieval of your objects while searching.
Any Map will do. Alternatively if you're not interested in learning about new classes simply use a matrix.
int matrix[][]=new int[10][10];
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In my code I have a pretty big loop and I need to create a new variable at the end of each iteration (integers). Is this possible? I read about a ScriptEngineManager class, but I'm not sure if this will be able to help. I suppose I could create a bunch of integers equal to 0, but I'm not exactly sure how many times I will need to create a new variable (it depends on the conditions of the loop). Hopefully this makes sense.
Use an array. In Javascript, place var results = [] before your loop and append results using results.push(value). In Java, you'll want to use an ArrayList. (Those are very different languages, by the way.)
Hopefully this makes sense.
Unfortunately, it doesn't.
In Java it makes no sense to create variables on the fly. It is extremely difficult to do, and once you have done it they are extremely difficult to use. (By contrast, it is easy to do in Javascript ...)
However, this just means that you need to do what you are trying to in a different way. For instance, the following does a computation in a loop and then saves the results in an (existing) ArrayList variable:
List<Integer> results = ArrayList<Integer>();
while (...) {
// Do computation ...
int result = ...
results.add(result);
}
// Now we have all of the results in 'results'
Or, if you want to bind each of the results to a distinct name, you could do something like this:
Map<String, Integer> results = HashMap<String, Integer>();
while (...) {
// Do computation ...
String name = ...
int result = ...
results.put(name, result);
}
Following is the way that i have implemented and helped me to fix my solution easily without much hurdles.
// Creating the array List
List accountList = new ArrayList();
for(int k=0;k < counter;k++){
accountList.add(k, (String)flowCtx.getValueAt("transitId"+m));
}
Iterating the loop and adding the objects into the arraylist with the index.
//Retrieving the object at run time with the help of the index
String a = accountList.get(i));
No, It is not possible to declare variables in java at runtime. But java provides java.util.map, which can be used like in the example below. We can assume that the key is the variable name.
Map<String, Object> declareVariableRuntime= new HashMap<String, Object>(); declareVariableRuntime.put("variableName", new Object());