Size has private access in ArrayList - java

I wrote a pretty standard bit of code utilizing String populated ArrayList but when I try running it, I get the following error:
error: size has private access in ArrayList.
The code is as follows:
System.out.println(testedArticles.size);

You are attempting to access a private member of ArrayList, part of its internal working that are not supposed to be used externally
If you want to get the size of the arraylist you want the method:
arraylist.size()
Why is it like this
This gives the ArrayList class the option to store size in whatever way it wants. Does it just return size, probably, but it could do a number of other things instead. For example it could calculate size lazily, in which it is only calculated if someone asked for it then it stores that value until it becomes invalid (as more objects are added). This would be useful if calculating size was expensive (very unlikely to be the case here), changed often and was called only occasionally.

There is nothing like ArrayList.size. You need to use .size() method.
You need to use
System.out.println(testedArticles.size());
instead of
System.out.println(testedArticles.size);

Related

Java: Wrapping objects in some type of collection to store duplicates in a set

I want to make a set of some type of collection (not sure which one yet) as a way of "storing duplicates" in a set. For example if I wanted to add the integer 5 with 39 additional copies I could put it into an arraylist at index 39. Thus if I were to get the size of the arraylist, I would know how many copies of 5 existed within the set.
There are a few other ways I could implement this but I have yet to decide on one. The main issue I'm having with implementing this is that I'm not sure how I can "dynamically" make arraylists (or whatever collection I may end up using) so that whenever someone were to call mySet.add(object), the object is first inserted into a unique arraylist then into the set itself.
Can anyone give me some ideas on how I could approach this?
EDIT:
Sorry I should have been more clear in my question. The point of the code that I'm writing is that we have a set-like collection that allows duplicates. And yes some of the associated methods will be re-written/will have to be re-written. Also my code should be written under the assumption that we do not know what type of object is being inserted(only one data type per set though) nor how many instances of the same object will be added nor how many different unique objects will be added.
I would rather go for using a Map like
HashMap list <Object, Integer>
where Object is the Object that you want to count and Integer is the count
You could try guava's MultiSet, I think it's what you want.
It can store the count of each object. What you need to do is just
multiSet.put(object);
And if it is put for the first time, like you said, a new list will be created, or its count will added by one.

Get the index of an object I just added to an ArrayList in Java/Android

I want to load a series of objects to an ArrayList, and return the index of where it was added so it can be used later directly from the ArrayList. It'd be akin to me loading a set of 5 frames for a graphic and calling the data for frame 3 directly from the list.
Upon looking around at a couple potential posts that may be related, I found something that was related, and made me wonder. Is there even a built in function to GET the index of a recently added object?
The link I am looking at that made me think of this was: ArrayList indexOf() returns wrong index?
Basically, the way I was looking at it was that I would do something along the lines of the following psuedocode:
private ArrayList<FrameData> mylistofframeshere = new ArrayList();
FrameData Framenumberone = new FrameData(constructorblah goes in here);
int wherediditgo = mylistofframeshere.add(Framenumberone);
Or I thought I could do something along the lines of
mylistofframeshere.getindex(Framenumberone);
My backgrounds in coding are more procedural based at this point, so I am more used to knowing what the index is, just in order to place the data to begin with. I looked around at the oracle documentation as well, with findings something similar to the above link. Any suggestions??
EDIT : I'm going to add some extra clarification in here, because I really didn't put enough effort into the example and explanation.
Another example of trying to use something like a direct index of a list would be if I had a set of tiles I wanted to use as terrain for a game or something. I would load a set of possible tiles for the area into a central ArrayList. Upon trying to place these tiles, I would just reference the pre-loaded object I have in my ArrayList in order to draw the appropriate bitmap/whatever.
I'm still a bit new to Java, so I'm willing to bet it's just something simple I'm overlooking in the mechanics of using these datatypes. I'll keep editing this until I get the explanation right.
When you add something to an ArrayList, it goes to the last available space. In other words:
List<FrameData> list = new ArrayList<FrameData>();
list.add(frame1);
FrameData frame = list.get(list.size() - 1); //frame == frame1
But I wonder why you would need to do that. If you explain more about what you are trying to achieve, there might be a different / better way to get to the same result.
There is a method like ArrayList.indexOf(object); , Try using that method to get index of the object
It all depends on what you want to use the index for. If you simply need to map each element in your list to a key so you can later retrieve the element with the key, you should perhaps consider using a HashMap. If you are more concerned with the ordering, you can use a List. As someone already answered, the index with be incremented as you add elements into the list. If you know the total number of frames you will have before hand, you can initialize an ArrayList by passing in the size as an argument to its constructor, then add each frame by manually specifying the index with list.add(0...size-1, element).
In short,
If you simply want to store and retrieve by your own key /
incremented key -> use a HashMap.
If ordering is important, use a list.
Instead of using ArrayList in this way, you can use a Map<Integer,FrameData>. you can replace Integer with anything which might fit better in your project.

How do I create an array of strings without specifying its length in the beginning?

I want to create an array of strings, but I do not know the length of it in the beginning. It's like the array length depends on many factors and it's only decided when I fill strings/words into it. however, processing does not allow me to do that, it asks me to specify the length in the beginning. How can I get rid of this?..Thanks for all help. Any suggestion will be appreciated.
Amrita
List<String> strs = new ArrayList<String>();
strs.add("String 1");
strs.add("String 2");
strs.add("String 3");
System.out.println(strs.size()); //3
System.out.println(strs.get(1)); //String 2
Something like that is all you need! You don't need to worry about resizing, copying stuff in memory or whatever - the list will just expand as it needs to. All of the performance details are taken care of and unless you're really interested in how it works, you don't need to read about those details to use it.
You can use ArrayList: http://processing.org/reference/ArrayList.html
I would start by using ArrayList and resizing it when necessary. Java pre-allocates memory for ArrayList so that not every resize means that the contents are copied in memory. Access to ArrayList is faster than to LinkedList (it's O(1) instead of O(n)). Only if you find that the resizing of the ArrayList takes too much time, would I think of switching to LinkedList.
Use the typed ArrayList as #berry120 suggests (otherwise, you'll need to cast from Object to String all the time).
Also, if it helps, Processing has some functions for handling Arrays (like append() and expand()). Look under Array Functions in the Processing reference.
Behind the scenes the above mentioned Array Functions use System.arraycopy(), if that's of any use.
You need to use a LinkedList structure: this gives you an easily expanded container array and takes an initial capacity in the constructor, rather than a set limit. This will also be more efficient than an ArrayList, which will copy it's contents every time you exceed the current capacity, rather than simply add to it.

How to resize ArrayList

I come from a C++ background and I want to have a matrix of
ArrayList<arrayList<E>> javamatrix
In C++ I would just do
std::vector<std::vector<T> > cppmatrix;
std::vector<T>vcol(cols);
cppmatrix.resize(rows,vcol);
I can't seem to find a built-in resize() function for ArrayLists for this task, so should I use another collection? Is no way to do this except using for loops with javamatrix.add()?
P.S I want it to be initialized in the constructor with its size as that size might be queried before I edit elements or add or remove.
There is no resize equivalent that automatically constructs and adds elements. You must do this yourself. However, ensureCapacity is equivalent to vector's reserve. It will ensure you have room, but not change the actual size.
You shouldn't need to resize arraylists. The size you initially pass in is just its starting size. If you attempt to add items beyond its current size, it will automatically resize.
From the documentation:
Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.
Mostly, a 'resize()' operation is not needed because (a) ArrayList's auto-resize as you add elements, and (b) it's unclear what values you would store in the ArrayList<>, e.g. 'null' is not very useful. E.g. in your case you'd probably need a loop anyway to create MatrixCell objects.
For those readers who want to know how to resize an ArrayList to make it smaller, it mystifies me why ArrayList was designed without a 'resize()' method. Perhaps it's because novice programmers are likely to see that method and then not realise that ArrayList<> auto-resizes.
In Java this idiom works to reduce the size of an ArrayList<>:
list.subList(n,list.size()).clear();
It works because the 'subList' returns a List backed by the original ArrayList<>, so therefore the 'clear()' operates on the original 'ArrayList<>'.
I know this question is very old already but this link may help java arraylist ensureCapacity not working , The code adds "Null" value in order to adjust the current size.
Instead of using purely ensureCapacity you can have ensureSize
public static void ensureSize(ArrayList<?> list, int size) {
list.ensureCapacity(size);
while (list.size() < size) {
list.add(null);
}
}

Java ArrayList<Double> IndexOutOfBoundsException Problem

I've got a Problem with ArrayList. I need it to store a result. Because I want to start with element n I tried to give the ArrayList a capacity with ensureCapacity(n+1) to use set(n,x) but I get an IndexOutOfBoundsException.
I tried to store n add(x) before the use of set and this works.
So I'd like to know why it doesn't work on my way and how to solve this because put n times a add(x) isn't a good style ;-)
When you change the capacity of an ArrayList it doesn't create any elements, it just reserves memory where there could be elements. You can check the size before and after adjusting the capacity and you will see that it does not change.
The purpose of changing the capacity is if you know in advance how many elements you will have, then you can avoid unnecessary repeated resizing as you add new elements, and you can avoid memory wastage from excess unused capacity.
If you don't like using your own loop and the list add method directly then there is another way. Create your ArrayList with the number of elements you want it directly like this:
final int MAX_ELEMENTS = 1000;
List<Integer> myList = new ArrayList<Integer>(
Collections.<Integer>nCopies(MAX_ELEMENTS, null));
Or, if you already have a list that you want to expand the size by n elements:
myList.addAll(Collections.<Integer>nCopies(n, null));
(Note, I assumed here that the list would be holding Integer objects, but you can change this to your custom type. If you are working with raw/pre-Java 5 types then just drop the generic declarations.)
As for your actual question: capacity != contents. An ArrayList internally has both a physical array and a count of what is actually in it. Increasing the capacity, changes the internal array so it can hold that many elements, however, the count does not change. You need to add elements to increase that count.
On the other hand, if you are just trying to set specific elements and know the maximum that you want to use, why not use an array directly? If you then need to pass this array to an API that takes Lists, then use Arrays.asList. The other classes could still change contents of your backing array but it would not be able to increase the size or capacity of it.
As others have answered, ensureCapacity() is just related to performance, is not frequently used by the common user.
From Bruce Eckel's Thinking in Java book:
In a private message, Joshua Bloch
wrote: "... I believe that we erred by
allowing implementation details (such
as hash table size and load factor)
into our APIs. The client should
perhaps tell us the maximum expected
size of a collection, and we should
take it from there. Clients can easily
do more harm than good by choosing
values for these parameters. As an
extreme example, consider Vector's
capacityIncrement. No one should ever
set this, and we shouldn't have
provided it. If you set it to any
non-zero value, the asymptotic cost of
a sequence of appends goes from linear
to quadratic. In other words, it
destroys your performance. Over time,
we're beginning to wise up about this
sort of thing. If you look at
IdentityHashMap, you'll see that it
has no low-level tuning parameters"
You are getting this exception because ensureCapacity() only makes sure that there is enough memory allocated for adding objects to an ArrayList, I believe this is in case you want to add multiple objects at once, without having to relocate memory.
To do what you want you would have to initiate the ArrayList with null elements first...
int n = 10; //capacity required
ArrayList foo = new ArrayList();
for( int i=0; i<=n; i++ ) {
foo.add(null);
}
Then you have objects in the List that you can reference via index and you wont receive the exception.
Perhaps you should rethink the choice of using List<Double>. It might be that a Map<Integer,Double> would be more appropriate if elements are to be added in an odd order.
Whether this is appropriate depends on knowledge about your usage that I don't have at the moment though.
Is the data structure eventually going to be completely filled, or is the data sparse?
what other people said about ensureCapacity() ...
you should write a class like DynamicArrayList extends ArrayList. then just overrride add(n,x) to do with for loop add(null) logic specified about.
ensureCapacity() has another purpose. It should be used in cases when you get to know the required size of the List after it has been constructed. If you know the size before it is constructor, just pass it as a an argument to the constructor.
In the former case use ensureCapacity() to save multiple copying of the backing array on each addition. However, using that method leaves the structure in a seemingly inconsistent state
the size of the backing array is increased
the size field on the ArrayList isn't.
This, however, is normal, since the capacity != size
Use the add(..) method, which is the only one that is increasing the size field:
ArrayList list = new ArrayList();
list.ensureCapacity(5); // this can be done with constructing new ArrayList(5)
for (int i = 0; i < list.size - 1; i ++) {
list.add(null);
}
list.add(yourObject);

Categories