I have run into these two documentations:
Java documentation for the class Array
Java documentation for the class Arrays
and I'm wondering what the difference is between these two classes. They both provide a different set of static methods, but why are they separate? What is the deeper difference? And what is the relation between them and with the normal instance of array like int[].
I notice that they are from totally different packages, but still hope to find some clarification. Thanks.
The differences are made fairly clear in the docs.
From Arrays.java:
This class contains various methods for manipulating arrays (such as sorting and searching). This class also contains a static factory that allows arrays to be viewed as lists.
From Array.java
The Array class provides static methods to dynamically create and access Java arrays.
Essentialy Array is an implementation of core Array operations - getting, setting and instantiation.
Arrays is a helper class for wrapping common Array operations (conversion between Arrays and Lists, sorting, searching for a value) without polluting the core Array "api".
Related
I was going through Java documentation, and I learned that methods in the Arrays class in Java are all static. I don't really understand the reason behind why they made it static.
For example, the following code violates the OO approach, because if I have a type, 'X', then all the methods which acts on it should be inside it:
int[] a = {34, 23, 12};
Arrays.sort(a);
It would be better if they have implemented the following way:
int[] a = {34, 23, 12};
a.sort();
Can anyone explain me a bit on this?
In Java there is no way to extend the functionally of an array. Arrays all inherit from Object but this gives very little. IMHO This is a deficiency of Java.
Instead, to add functionality for arrays, static utility methods are added to classes like Array and Arrays. These methods are static as they are not instance methods.
Good observation. Observe also that not every array can be sorted. Only arrays of primitives and Objects which implement the Comparable interface can be sorted. So a general sort() method that applies to all arrays is not possible. And so we have several overloaded static methods for each of the supported types that are actually sortable.
Update:
#Holger correctly points out in the comments below that one of the overloaded static methods is indeed Arrays.sort(Object[]) but the docs explicitly state:
All elements in the array must implement the Comparable interface.
So it doesn't work for Objects that don't implement Comparable or one of its subinterfaces.
First of all, Arrays is an utility class, which does exactly that: exposes static methods. It is separate from any arr[] instances and has no OO relation to it. There are several classes like that, like Collections or various StringUtils.
Arrays are collections, they are used to store data. Arrays.sort() is an algorithm which sorts the collection. There may be many other algorithms which sort data in different way, all of them would be used in the same way: MyAlgorithm.doSthWithArray(array). Even if there was a sort() method on an array (it would then have to be a SortableArray, because not all Objects can be sorted automatically), all other algorithms would have to be called the old way anyway. Unless there was a visitor pattern introduced... But that makes things too complicated, hence, there is no point.
For a java Collection there's Collections.sort(), even in C++ there is std::sort which works similarly, as does qsort in C . I don't see a problem here, I see consistency.
Static Methods are sometimes used for utility purpose.
So Arrays is utility class for general purpose array operations.
Similarly, Collections is also Util class where utility methods are given.
Arrays are kind of like second-class generics. When you make an array it makes a custom class for the array type, but it's not full featured because they decided how arrays would work before they really fleshed out the language.
That, combined with maintaining backwards compatibility, means that Arrays are stuck with an archaic interface.
It's just an old part of the API.
An array is not an object which stores state, beyond the actual values of int the array. In other words, it's just a "dumb container". It doesn't "know" any behaviour.
A utility class is a class which has just public static methods which are stateless functions. Sorting is stateless because there's nothing remembered between calls to that method. It runs "standalone", applying its formula to whatever object is passed in, as long as that object is "sortable". A second instance of an Arrays class would have behaviour no different, so just have the one static instance.
As Dariusz pointed out, there are different ways of sorting. So you could have MyArrays.betterSort(array) as well as Arrays.sort(array).
If you wanted to have the array "know" how best to sort its own members, you'd have to have your own array class which extends an array.
But what if you had a situation where you wanted different sorting on different times on the the same array? A contrived example, maybe, but there are plenty of similar real-world examples.
And now you're getting complicated. Maybe an array of type T sort differently than type S ....
It's made simple with a static utility and the Comparator<T> interface.
For me this is the perfect solution. I have an array, and I have a class, Arrays, which operates over the data in the array. For example, you may want to hold some random numbers and you will never want to sort or any other utility method you will receive behavior which you don't want. That's why in code design it is good to separate data from the behavior.
You can read about the single responsibility principle.
The Arrays class contains methods that are independent of state, so therefore they should be static. It's essentially a utility class.
While OOP principles don't apply, the current way is clearer, concise, and more readable since you don't have to worry about polymorphism and inheritance. This all reduces scope, which ultimately reduces the chances that you screw something up.
Now, you may ask yourself "Why can't I extend the functionality of an array in Java?". A nice answer is that this introduces potential security holes, which could break system code.
I am trying to write a class using so that I can implement a circular buffer of any type of data. There are two options that I see right now. First, I create a class using generics where the generic type would be used to determine the type of array that I want to initialise for the circular buffer. Here, I would have to use the array of the class. Second, I create an abstract base class defining the common components and extend this class for the implementation of different types of buffers that I want to use. For instance, if I want to create an instance of circular buffer of type int, I can create it in the implementation of my child class. Here, I can use the primitive datatypes to create the arrays. My application is real-time and would access these buffers in real-time. So, I would want to know which is an efficient solution.
The second approach will perform better because unboxing and (in particular) autoboxing have a performance hit.
The collections will also have a considerably smaller memory footprint too, so that's another benefit.
These reasons are why collection frameworks like GS Collections (now Eclipse Collections I believe) and Guava include primitive implementations of their collections.
The downside is that you will have more code to write up-front, and you won't have a single class that can be used in all circumstances.
I just started with lists in Java and I'm confused with all this.
So basically we have ArrayList and LinkedList which can be defined like
LinkedList<String> s = new LinkedList<String>();
ArrayList<String> s = new ArrayList<String>();
But then we also have LinkedIntList which can be defined like for example:
class LinkedIntList {
private ListNode first;
private int size;
LinkedIntList () {
first=null;
size=0;
}
LinkedIntList(LinkedIntList l) {
first = l.getFirst();
size=l.size();
}
ListNode getFirst() {return first;}
int size() {return size;}
}
But this is my problem, why define LinkedIntList using a class? What is the difference comparing to LinkedLists where we just define like I stated.
I can't understand why a class is being used. If this is a 'new type' of array why using a class instead of declaring it normally?
Sorry if this sounds weird, but I'm a beginner and really need help at this.
Thank you!
A List in java, is an ordered collection. I suppose you are a beginner and confused with syntax. If you have java decompiler, you can see that LinkedList and ArrayList are also classes. Which means somewhere some good person has done the coding for you and provided you a class which is similar to your "LinkedIntList" and provided you out of the box.
You don't need to create a new class if java provides sufficient functionality for you.
But sometimes, the out of the box classes are not sufficient for our requirements. In that case we have to write our own implementation of classes, such as your class "LinkedIntList".
In this case, it seems you need size and one element hence you are creating it on your own.
LinkedList is a class defined in the java.util package, and it's already provided to you. It exploits a feature called Generics that allows you to provide the type of objects that will populate the list. You basically take it as a black box: in most cases, you don't care about LinkedList actual implementation, but only about its interface (that is, the methods it exposes to you).
The class LinkedIntList that you provided does not feature genericity, but is simply an implementation of a linked list where each item is a ListNode. I guess a ListNode contains an integer, otherwise the name LinkedIntList wouldn't make much sense.
Anyway, you could discard this implementation (although is good for learning) and simply declare
LinkedList<Integer> myLinkedList = new LinkedList<Integer>();
If you want to know more about generics, take a look at the java tutorials.
In your first example,
LinkedList<String> s = new LinkedList<String>();
it is the implementation of LinkedList defined in the stardard library, specifically from package java.util. See here: http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
You can look for its source code (1000+ lines long so I won't be posting it here) and compare it to your custom implementation of LinkedIntList.
Basically, Java already provided a default implementation of LinkedList(your first example) but everyone can still write(a class) and use their own implementation (your second example).
You're question isn't clear, but I'll try to explain to you what Lists are essentially.
Lists are a type of data structure, not only in Java but in a lot of programming language. Arrays are also a type of data structure. Data structures hold and manage data in an organized manner.
In Java, the main difference between a List and an Array is that a List has dynamic size, while an Array is of fixed size set when the Array was declared.
All Lists in Java are implementation of the List interface. If you don't know what interfaces are, I suggest you learn about it, but basically it means that all Lists can do the same basic set of things for you, but do them differently internally.
For example, ArrayList uses Arrays internally in order to expand or diminish the List as necessary (implement the dynamic size). LinkedList implements things differently internally, using nodes that are connected to each other. But they both offer the same basic sets of operations to the programmer, defined in the List interface (although one may offer additional methods the other doesn't).
Because the differ in their inner implementation, they might differ in performance for different operations. They have different algorithms to do things (for example, access a value in an index), with different 'speeds' (complexities) of doing so.
Most of the time ArrayList will be the right, simpler choice. This answer talks about when to prefer one over the other.
Hope this helps.
A java List is an ordered collection of objects, this java.util.List is actually an interface (contract) that defined what a list should behave like.
There are multiple variations (implementations) of List in the java standard JDK, while each is different from the other, they honor the contract defined in List (the ordered aspect for example). These implementations are concrete classes and you choose from in your code.
LinkedList and ArrayList you mentioned are JDK implementations of List.
The class you shared (LinkedIntList) is a custom made structure of objects, that neither part of the JDK, nor implement the java List interface.
LinkedList is a part of Java platform class in java.util package and it is widely used in different tasks. And it supports Generics .
LinkedIntList is a custom implementation just to show you how single-linked list coudl be implemented.
You can find more about different algorithms and structures and also complexity here
Is it fair to group the following:
Arrays, Collections, Sets, Maps
into a group called Collections or is there another single word or two words (other than object) that best describes Arrays, Collections, Sets and Maps.
Sorry if this is not the right category or not a suitable question. I am learning about these topics and need to find a single word that best describes all of these.
Collections sound fine. Data Structures also sound equally good.
As the Java Reference Docs can tell you, Arrays, Sets and Maps are all part of the Java Collections Framework. Thus not only are those three generally varieties of collections, but they are formally defined as such by Java.
I believe Set extends Collection, so it's not a new category unto itself.
If you look at the class hierarchy you'll see just two categories: Collection and Map. The latter has keys separate from values; the former does not.
look on the java doc of collection. you will see that map is not extend interface collection, so data structure is better.
Arrays and Collections are classes with all static methods to help manipulating arrays of primitives,classes and the later for classes implementing Map,List,Set.
Ex: Collections sort()(takes comparator to sort different classes),addAll,freq or Arrays asList,sort,binarysearch
Well, it seems to me ArrayLists make it easier to expand the code later on both because they can grow and because they make using Generics easier. However, for multidimensional arrays, I find the readability of the code is better with standard arrays.
Anyway, are there some guidelines on when to use one or the other? For example, I'm about to return a table from a function (int[][]), but I was wondering if it wouldn't be better to return a List<List<Integer>> or a List<int[]>.
Unless you have a strong reason otherwise, I'd recommend using Lists over arrays.
There are some specific cases where you will want to use an array (e.g. when you are implementing your own data structures, or when you are addressing a very specific performance requirement that you have profiled and identified as a bottleneck) but for general purposes Lists are more convenient and will offer you more flexibility in how you use them.
Where you are able to, I'd also recommend programming to the abstraction (List) rather than the concrete type (ArrayList). Again, this offers you flexibility if you decide to chenge the implementation details in the future.
To address your readability point: if you have a complex structure (e.g. ArrayList of HashMaps of ArrayLists) then consider either encapsulating this complexity within a class and/or creating some very clearly named functions to manipulate the structure.
Choose a data structure implementation and interface based on primary usage:
Random Access: use List for variable type and ArrayList under the hood
Appending: use Collection for variable type and LinkedList under the hood
Loop and process: use Iterable and see the above for use under the hood based on producer code
Use the most abstract interface possible when handing around data. That said don't use Collection when you need random access. List has get(int) which is very useful when random access is needed.
Typed collections like List<String> make up for the syntactical convenience of arrays.
Don't use Arrays unless you have a qualified performance expert analyze and recommend them. Even then you should get a second opinion. Arrays are generally a premature optimization and should be avoided.
Generally speaking you are far better off using an interface rather than a concrete type. The concrete type makes it hard to rework the internals of the function in question. For example if you return int[][] you have to do all of the computation upfront. If you return List> you can lazily do computation during iteration (or even concurrently in the background) if it is beneficial.
The List is more powerful:
You can resize the list after it has been created.
You can create a read-only view onto the data.
It can be easily combined with other collections, like Set or Map.
The array works on a lower level:
Its content can always be changed.
Its length can never be changed.
It uses less memory.
You can have arrays of primitive data types.
I wanted to point out that Lists can hold the wrappers for the primitive data types that would otherwise need to be stored in an array. (ie a class Double that has only one field: a double) The newer versions of Java convert to and from these wrappers implicitly, at least most of the time, so the ability to put primitives in your Lists should not be a consideration for the vast majority of use cases.
For completeness: the only time that I have seen Java fail to implicitly convert from a primitive wrapper was when those wrappers were composed in a higher order structure: It could not convert a Double[] into a double[].
It mostly comes down to flexibility/ease of use versus efficiency. If you don't know how many elements will be needed in advance, or if you need to insert in the middle, ArrayLists are a better choice. They use Arrays under the hood, I believe, so you'll want to consider using the ensureCapacity method for performance. Arrays are preferred if you have a fixed size in advance and won't need inserts, etc.