While reading collections in java and browsing some of the questions on stackoverflow, I came across this question:
Method for adding Objects into a fixed collection(Array) in Java
Here an Array has been referred to as fixed collection. Conceptually, is it legitimate to call an Array a 'fixed collection' or is it a self-contradicting phrase?
A collection framework is basically a framework to store and retrieve the collection of java objects efficiently.
A very good link about overview of data structure is here
As per this link
There are fourteen collection interfaces. The most basic interface is Collection. These interfaces extend Collection: Set, List, SortedSet, NavigableSet, Queue, Deque,
BlockingQueue and BlockingDeque.
The other collection interfaces, Map, SortedMap, NavigableMap, ConcurrentMap and ConcurrentNavigableMap do not extend Collection, as they represent mappings
rather than true collections. However, these interfaces contain collection-view operations, which allow them to be manipulated as collections.
Now coming back to array its not part of collection framework but logically its collection as it can store collection of objects. Even if you develop your custom class that can store bunch of objects you can logically call it collection object.
An array is a collection if you define a collection as a container of elements.
Of course an array does not implement the Collection interface, but calling Arrays.asList(arr) on an array actually gives you a fixed size List view of that array, so you can say an array is almost equivalent to a fixed length random access List (A List is a Collection).
Related
Prompted by the example provided at 37:19 of this talk by Stuart Marks on Java Collections, I was wondering what is the best way to make a List of objects immutable from a space efficiency perspective.
In my example, I have a List of objects that I retrieve from a database:
List<MyObject> myObjects = myRepository.getMyObjectsThatFitCriteria();
To make this List immutable I can think of three ways to do it
Wrap it in Collections.unModifiableList() but this creates another object and the underlying list itself is still modifiable
Stream over the myObjects list and collect it to an unmodifiable list but this might have a performance impact, particularly if the list is large
Use the List.copyOf() static factory method introduced in Java 9 but this creates another copy of the myObjects list, impacting memory and storage.
As mentioned by #VGR in the comment, Collections.unmodifiableList will not copy the elements into a new list, but rather wrap it and prevent modifications on it.
If you're using Spring Data JPA for repository support, it's a good idea to leverage its support for streams: https://www.baeldung.com/spring-data-java-8
Streams are a good way to avoid large memory consumption if the list is large. It does not change the source collection and allows lazy consumption.
Wrap it in Collections.unModifiableList() but this creates another object and the underlying list itself is still modifiable.
You still need to create a list so there is no way around that. But you can always reassign to the same list to effectively remove the reference from access.
list = Collections.unModifiableList(list);
The original list internally is simply referred to (thus not copied) for immutable methods like size(). Any other methods that would allow changes are overridden with methods that throw exceptions if they are invoked. So the overhead is minimal.
Note that unless the contained objects are immutable, they are still subject to alteration.
My program has to pass a lot of arrays between threads. I want a collection that can accept an array, and then a contains method will specify whether a Set/Map contains the array (i.e. it is a duplicate or has already been processed by the thread). I assume this collection would have to use Arrays.equals(a1, a2), because the Object.equals() method will not work on arrays. Is it possible to write a collection that works like this, or would it fail when autoboxing from, say, int[] to Integer[]?
Use a wrapper for Array which overrides hashCode() and equals() like Arrays.asList().
BTW, you should avoid using arrays and opt for Collections whenever possible. I also recommend you use immutable data structures for multi-threading. Using a mutable object in a Set or as the key of a Map is a terrible idea anyways.
Maps in Java do not inherit from the interface "Collection" though in the most online "Tutorials" Maps are explained in the same category as Sets, Lists and Queues.
Do the Maps nevertheless belong to the Collection Framework?
The best description of the Collection is at the beginning of Java Collection Tutorial.
A collection — sometimes called a container — is simply an object that groups multiple elements into a single unit. Collections are used to store, retrieve, manipulate, and communicate aggregate data. Typically, they represent data items that form a natural group, such as a poker hand (a collection of cards), a mail folder (a collection of letters), or a telephone directory (a mapping of names to phone numbers).
Furthermore the tutorial lists the core collection interfaces, which all of them follow the paradigm stated above:
The following list describes the core collection interfaces:
Collection — the root of the collection hierarchy. A collection represents a group of objects known as its elements. The Collection interface is the least common denominator that all collections implement and is used to pass collections around and to manipulate them when maximum generality is desired. Some types of collections allow duplicate elements, and others do not. Some are ordered and others are unordered. The Java platform doesn't provide any direct implementations of this interface but provides implementations of more specific subinterfaces, such as Set and List. Also see The Collection Interface section.
Set — a collection that cannot contain duplicate elements. This interface models the mathematical set abstraction and is used to represent sets, such as the cards comprising a poker hand, the courses making up a student's schedule, or the processes running on a machine. See also The Set Interface section.
List — an ordered collection (sometimes called a sequence). Lists can contain duplicate elements. The user of a List generally has precise control over where in the list each element is inserted and can access elements by their integer index (position). If you've used Vector, you're familiar with the general flavor of List. Also see The List Interface section.
Queue — a collection used to hold multiple elements prior to processing. Besides basic Collection operations, a Queue provides additional insertion, extraction, and inspection operations.
Queues typically, but do not necessarily, order elements in a FIFO (first-in, first-out) manner. Among the exceptions are priority queues, which order elements according to a supplied comparator or the elements' natural ordering. Whatever the ordering used, the head of the queue is the element that would be removed by a call to remove or poll. In a FIFO queue, all new elements are inserted at the tail of the queue. Other kinds of queues may use different placement rules. Every Queue implementation must specify its ordering properties. Also see The Queue Interface section.
Map — an object that maps keys to values. A Map cannot contain duplicate keys; each key can map to at most one value. If you've used Hashtable, you're already familiar with the basics of Map. Also see The Map Interface section.
So Map is a Collection although it doesn't really have to implement the Collection interface.
The Map interface is not an extension of Collection interface. Instead the interface starts of it’s own interface hierarchy for maintaining key-value associations.
Check out the official tutorial, especially the Lesson: Interfaces:
[...]Core collection interfaces are the foundation of the Java Collections Framework. As you can see in the following figure, the core collection interfaces form a hierarchy.
and further:
The following list describes the core collection interfaces:
Collection [...]
Set [...]
List [...]
Queue [...]
Map [...]
Conceptually maps are definitely collections, have been since Smalltalk. Java's type-hierarchy is not meant to manage conceptual relations but rather a pragmatic relationship, specifically to say which methods have to be implemented.
For map-like collections these are very different than for non-map-like. For example with maps you have have to have put(key, value) and get(key) (or similar, if you are working with asscociation-objects), whereas non-map-like have to have iterator() and add().
The reason is that the Collections work with the set of values where as the Map work in the form of key-value pairs.
What is the difference between Collection and List in Java? When should I use which?
First off: a List is a Collection. It is a specialized Collection, however.
A Collection is just that: a collection of items. You can add stuff, remove stuff, iterate over stuff and query how much stuff is in there.
A List adds the information about a defined sequence of stuff to it: You can get the element at position n, you can add an element at position n, you can remove the element at position n.
In a Collection you can't do that: "the 5th element in this collection" isn't defined, because there is no defined order.
There are other specialized Collections as well, for example a Set which adds the feature that it will never contain the same element twice.
Collection is the root interface to the java Collections hierarchy. List is one sub interface which defines an ordered Collection, other sub interfaces are Queue which typically will store elements ready for processing (e.g. stack).
The following diagram demonstrates the relationship between the different java collection types:
Java API is the best to answer this
Collection
The root interface in the collection
hierarchy. A collection represents a
group of objects, known as its
elements. Some collections allow
duplicate elements and others do not.
Some are ordered and others unordered.
The JDK does not provide any direct
implementations of this interface: it
provides implementations of more
specific subinterfaces like Set and
List. This interface is typically used
to pass collections around and
manipulate them where maximum
generality is desired.
List (extends Collection)
An ordered collection (also known as a
sequence). The user of this interface
has precise control over where in the
list each element is inserted. The
user can access elements by their
integer index (position in the list),
and search for elements in the list.
Unlike sets, lists typically allow
duplicate elements. More formally,
lists typically allow pairs of
elements e1 and e2 such that
e1.equals(e2), and they typically
allow multiple null elements if they
allow null elements at all. It is not
inconceivable that someone might wish
to implement a list that prohibits
duplicates, by throwing runtime
exceptions when the user attempts to
insert them, but we expect this usage
to be rare.
List and Set are two subclasses of Collection.
In List, data is in particular order.
In Set, it can not contain the same data twice.
In Collection, it just stores data with no particular order and can contain duplicate data.
Collection is the Super interface of List so every Java list is as well an instance of collection. Collections are only iterable sequentially (and in no particular order) whereas a List allows access to an element at a certain position via the get(int index) method.
Collection is the main interface of Java Collections hierarchy and List(Sequence) is one of the sub interfaces that defines an ordered collection.
Collection is a high-level interface describing Java objects that can contain collections of other objects. It's not very specific about how they are accessed, whether multiple copies of the same object can exist in the same collection, or whether the order is important. List is specifically an ordered collection of objects. If you put objects into a List in a particular order, they will stay in that order.
And deciding where to use these two interfaces is much less important than deciding what the concrete implementation you use is. This will have implications for the time and space performance of your program. For example, if you want a list, you could use an ArrayList or a LinkedList, each of which is going to have implications for the application. For other collection types (e.g. Sets), similar considerations apply.
What is the need of Collection framework in Java since all the data operations(sorting/adding/deleting) are possible with Arrays and moreover array is suitable for memory consumption and performance is also better compared with Collections.
Can anyone point me a real time data oriented example which shows the difference in both(array/Collections) of these implementations.
Arrays are not resizable.
Java Collections Framework provides lots of different useful data types, such as linked lists (allows insertion anywhere in constant time), resizeable array lists (like Vector but cooler), red-black trees, hash-based maps (like Hashtable but cooler).
Java Collections Framework provides abstractions, so you can refer to a list as a List, whether backed by an array list or a linked list; and you can refer to a map/dictionary as a Map, whether backed by a red-black tree or a hashtable.
In other words, Java Collections Framework allows you to use the right data structure, because one size does not fit all.
Several reasons:
Java's collection classes provides a higher level interface than arrays.
Arrays have a fixed size. Collections (see ArrayList) have a flexible size.
Efficiently implementing a complicated data structures (e.g., hash tables) on top of raw arrays is a demanding task. The standard HashMap gives you that for free.
There are different implementation you can choose from for the same set of services: ArrayList vs. LinkedList, HashMap vs. TreeMap, synchronized, etc.
Finally, arrays allow covariance: setting an element of an array is not guaranteed to succeed due to typing errors that are detectable only at run time. Generics prevent this problem in arrays.
Take a look at this fragment that illustrates the covariance problem:
String[] strings = new String[10];
Object[] objects = strings;
objects[0] = new Date(); // <- ArrayStoreException: java.util.Date
Collection classes like Set, List, and Map implementations are closer to the "problem space." They allow developers to complete work more quickly and turn in more readable/maintainable code.
For each class in the Collections API there's a different answer to your question. Here are a few examples.
LinkedList: If you remove an element from the middle of an array, you pay the cost of moving all of the elements to the right of the removed element. Not so with a linked list.
Set: If you try to implement a set with an array, adding an element or testing for an element's presence is O(N). With a HashSet, it's O(1).
Map: To implement a map using an array would give the same performance characteristics as your putative array implementation of a set.
It depends upon your application's needs. There are so many types of collections, including:
HashSet
ArrayList
HashMap
TreeSet
TreeMap
LinkedList
So for example, if you need to store key/value pairs, you will have to write a lot of custom code if it will be based off an array - whereas the Hash* collections should just work out of the box. As always, pick the right tool for the job.
Well the basic premise is "wrong" since Java included the Dictionary class since before interfaces existed in the language...
collections offer Lists which are somewhat similar to arrays, but they offer many more things that are not. I'll assume you were just talking about List (and even Set) and leave Map out of it.
Yes, it is possible to get the same functionality as List and Set with an array, however there is a lot of work involved. The whole point of a library is that users do not have to "roll their own" implementations of common things.
Once you have a single implementation that everyone uses it is easier to justify spending resources optimizing it as well. That means when the standard collections are sped up or have their memory footprint reduced that all applications using them get the improvements for free.
A single interface for each thing also simplifies every developers learning curve - there are not umpteen different ways of doing the same thing.
If you wanted to have an array that grows over time you would probably not put the growth code all over your classes, but would instead write a single utility method to do that. Same for deletion and insertion etc...
Also, arrays are not well suited to insertion/deletion, especially when you expect that the .length member is supposed to reflect the actual number of contents, so you would spend a huge amount of time growing and shrinking the array. Arrays are also not well suited for Sets as you would have to iterate over the entire array each time you wanted to do an insertion to check for duplicates. That would kill any perceived efficiency.
Arrays are not efficient always. What if you need something like LinkedList? Looks like you need to learn some data structure : http://en.wikipedia.org/wiki/List_of_data_structures
Java Collections came up with different functionality,usability and convenience.
When in an application we want to work on group of Objects, Only ARRAY can not help us,Or rather they might leads to do things with some cumbersome operations.
One important difference, is one of usability and convenience, especially given that Collections automatically expand in size when needed:
Collections came up with methods to simplify our work.
Each one has a unique feature:
List- Essentially a variable-size array;
You can usually add/remove items at any arbitrary position;
The order of the items is well defined (i.e. you can say what position a given item goes in in the list).
Used- Most cases where you just need to store or iterate through a "bunch of things" and later iterate through them.
Set- Things can be "there or not"— when you add items to a set, there's no notion of how many times the item was added, and usually no notion of ordering.
Used- Remembering "which items you've already processed", e.g. when doing a web crawl;
Making other yes-no decisions about an item, e.g. "is the item a word of English", "is the item in the database?" , "is the item in this category?" etc.
Here you find use of each collection as per scenario:
Collection is the framework in Java and you know that framework is very easy to use rather than implementing and then use it and your concern is that why we don't use the array there are drawbacks of array like it is static you have to define the size of row at least in beginning, so if your array is large then it would result primarily in wastage of large memory.
So you can prefer ArrayList over it which is inside the collection hierarchy.
Complexity is other issue like you want to insert in array then you have to trace it upto define index so over it you can use LinkedList all functions are implemented only you need to use and became your code less complex and you can read there are various advantages of collection hierarchy.
Collection framework are much higher level compared to Arrays and provides important interfaces and classes that by using them we can manage groups of objects with a much sophisticated way with many methods already given by the specific collection.
For example:
ArrayList - It's like a dynamic array i.e. we don't need to declare its size, it grows as we add elements to it and it shrinks as we remove elements from it, during the runtime of the program.
LinkedList - It can be used to depict a Queue(FIFO) or even a Stack(LIFO).
HashSet - It stores its element by a process called hashing. The order of elements in HashSet is not guaranteed.
TreeSet - TreeSet is the best candidate when one needs to store a large number of sorted elements and their fast access.
ArrayDeque - It can also be used to implement a first-in, first-out(FIFO) queue or a last-in, first-out(LIFO) queue.
HashMap - HashMap stores the data in the form of key-value pairs, where key and value are objects.
Treemap - TreeMap stores key-value pairs in a sorted ascending order and retrieval speed of an element out of a TreeMap is quite fast.
To learn more about Java collections, check out this article.