Is there some interface that will allow for iteraction of arrays and java.util.Lists?
Seeing as how the for-each loop can iterate both it seems to me there must be some sort of base 'iterable' that is being traversed in both cases.
So, can i setup a method parameter that accepts either Foo[], or List?
We have lots of old code (which we won't be updating), that calls a few low level methods (which i'd like to update) that are expecting arrays.
Our new code is converting from Lists (specifically ArrayLists most of the time) to arrays using List's toArray method, and i'd like to be able to skip this step.
I've seen this post which shows the implementation, but I'm not sure how it might help.
Can this be done?
No, the language specification explicitly calls out arrays separately. Arrays don't implement Iterable<T>, which is the "normal" interface used by the enhanced for loop other than for arrays. From section 14.14.2 of the JLS:
The enhanced for statement has the form:
EnhancedForStatement:
for ( VariableModifiers Type Identifier: Expression) Statement
The Expression must either have type Iterable or else it must be of an array type (ยง10.1), or a compile-time error occurs.
The two cases are then handled separately.
Converting from arrays to lists is easy of course - but it sounds like you need to do this the other way round. There's really no "pleasant" way of doing this - and creating the array requires copying everything, of course.
How much work would it be to convert at least the most heavily used bits of the API to use lists?
You can write method overloads of course, e.g.
public void foo(String[] array)
{
foo(Arrays.asList(array));
}
public void foo(List<String> list)
{
// Use the list
}
... but doing that for your old code will still involve work, as the real implementation is in terms of the list, not the array.
Java could have made Foo[] a subtype of Iterable<Foo>; unfortunately that won't work on primitive arrays because Java doesn't support primitive type arguments, so we don't have this nicety.
I think arrays are just special cased in the for loop's implementation.
One thing you can do is overload your methods:
public void foo(MyClass[] stuff) {
foo(Arrays.asList(stuff));
}
public void foo(Collection<MyClass> stuff) {
// stuff
}
Or the other way around:
public void foo(MyClass[] stuff) {
// stuff
}
public void foo(Collection<MyClass> stuff) {
foo(stuff.toArray(new MyClass[stuff.size()]));
}
There is not such a common interface, an Array does not implement Iterable.
What you can do is to overload you method:
public void mymethod(String ... strings) {
mymethod(Arrays.asList(strings));
}
public void mymethod(List<String> strings) {
// do what you need
}
Related
I'm reading J. Bloch's Effective Java and now I'm at inheritance vs composition section. As far as I understood he said that inheritance is not always good.
A related cause of fragility in subclasses is that their superclass
can acquire new methods in subsequent releases. Suppose a program
depends for its security on the fact that all elements inserted into
some collection satisfy some predicate. This can be guaranteed by
subclassing the collection and overriding each method capable of
adding an element to ensure that the predicate is satisfied before
adding the element. This works fine until a new method capable of
inserting an element is added to the superclass in a subsequent
release.
But why doesn't it work? The superclass is just the Collection interface and if we add a new method we just a compile-time error. That's not harmful ever...
Suppose you have a Collection superclass in some library v1.0:
public class MyCollection {
public void add(String s) {
// add to inner array
}
}
You subclass it in order to only accept Strings that have length 5:
public class LimitedLengthCollection extends MyCollection {
#Override
public void add(String s) {
if (s.length() == 5) {
super.add(s);
}
}
}
The contract, the invariant of this class is that it will never contain a String that doesn't have length 5.
Now version 2.0 of the library is released, and you start using it. The base class is modified to:
public class MyCollection {
public void add(String s) {
// add to inner array
}
public void addMany(String[] s) {
// iterate on each element and add it to inner array
}
}
and your subclass is left unmodified. Now users of your subclass can do
LimitedLengthCollection c = new LimitedLengthCollection();
c.addMany(new String[] {"a", "b", "c"});
and the contract of your subclass is thus broken. It was supposed to only accept Strings of length 5, and it doesn't anymore, because an additional method has been added in the superclass.
The problem is not that inheritance could not work.
The problem is that with inheritance the developer can not enforce some behaviour (like the example of the collection that satisfy some predicate) .
When we create a new class rarely it really is a specialized type of another. More often it is something new that use other classes.
So rarely we need inheritance and more often we need to create a class that use other classes to so something.
The IS A vs HAS A
You have to ask yourself:
Class B IS A new sub type of Class A that do the same things of A in different ways ?
or
Class B HAS A class inside to do something different from
what A is intented to do ?
And know that more often the right answer the latter.
if we add a new mehtod we just a compile-time error
That is true only when an abstract method is added to the superclass/interface. If a non-abstract method is added, it is perfectly valid not to override that new method.
Because it (in general) will break the client code that has implemented the Collection class.
In this particular example the security will be broken because malicious users would be able to insert items by using the non yet overridden method that was added after you have shipped your code.
Basing your code on inheriting classes you do not control may bite you in the future.
I have a String which can either be of Double or Integer type or some other type. I first need to create a Double or Integer object and then send it over to a overloaded method. Here's my code so far;
public void doStuff1(object obj, String dataType){
if ("Double".equalsIgnoreCase(dataType)) {
doStuff2(Double.valueOf(obj.toString()));
} else if ("Integer".equalsIgnoreCase(dataType)) {
doStuff2(Integer.valueOf(obj.toString()));
}
}
public void doStuff2(double d1){
//do some double related stuff here
}
public void doStuff2(int d1){
//do some int related stuff here
}
I'd like to do this without if/else, with something like this;
Class<?> theClass = Class.forName(dataType);
The problem is 'theClass' still can't be cast to either double or int. I would be gratefull for any ideas.
Thanks.
Found a related thread; Overloading in Java and multiple dispatch
This is not just a problem of dealing with primitive types.
Which method to call is decided in compile time, that is, if you want to be able to call different methods depending on the type of the arguments, you'll need several calls (i.e. you need the if-construct).
In other words, it wouldn't work even if doStuff2 took Integer and Double as arguments (your code is basically as good as it gets).
(In fancy words, this is due to the fact that Java has single dispatch. To emulate multiple dispatch you either need to use conditional statements or a visitor pattern.)
Since the method call is decided at compile time as the another answer told you, overloading won't work for you. I think that this problem can be solved with inheritance. So you write a base class with yourMethod() and override it in your derived classes.
As aioobe says, the choice between overloaded methods is made at compile time based on the static types of the arguments.
If you want to simulate overload choice at runtime, you will need to do some complicated runtime analysis of the different possible methods. It would go something like this:
get all declared methods of the class that declared doStuff2.
filter out the methods whose name is not doStuff2.
filter out the methods whose argument type cannot be assigned from the (dynamic) type of the argument value.
of the remaining methods, pick the one that is the best match ... taking care to deal with "ties" as ambiguous.
This will be tricky to code, and trickier if you also throw in handling of primitive types. It will also make the method calls expensive.
Frankly, some kind of hard-wired dispatching is much simpler. If you don't like if / else tests (or switching on a String in Java 7), then you could do something like this.
Map<String, Operation> map = ...
map.put("Double", new Operation(){
public void doIt(Object obj) {
doStuff2((Double) obj);
}});
map.put("Integer", new Operation(){
public void doIt(Object obj) {
doStuff2((Integer) obj);
}});
...
map.get(typeName).doIt(obj);
... which at least allows you to "plug in" support for new types dynamically.
If you resort to reflection, you'll only have to deal specially with primitive types. So your technique can work, but with the addition of a few explicit tests. If you need to reflectively find a method that accepts a primitive double, use double.class.
I really admire java features and I don't want to give up using it for the next problem:
I have a class that might be inherited, and inside of it is a private ArrayList arr; So the setter function is ok , but the getter function return arr; returns the reference to that variable which anyone capable of editing that whole array which I don't want and private wouldn't make any sense !
In C++ I would just return const arr; and it would return constant reference to the variable.
I so much need the variable not to be cloned or manually copied because there are so many calculations that require to (READ ONLY the variable) WHY there is no const returning in java ???? is there any way I could escape copying ?
p.s (final ArrayList<Integer> arr;) isn't an option cause that array always changes size or element values.
If I couldn't find a fix to that I'm threatening to go back to C++ or make everything public and you should never get my software :D
EDIT: one more important question: Am I asking for something that's not good (Software engineering wise) I mean if JAVA creators thought of not having const reference (returning Read only references) then I must be asking for something that can be handled in other way. or my program design is wrong I'm so confused.
Wrap the return value with java.util.Collections.unmodifiableList. It does not make a copy of the data, but wraps the original list, and delegates read-only operations to the underlying list. Operations which would modify the list are rejected at runtime via UnsupportedOperationException.
Your
return arrayList;
becomes
return Collections.unmodifiableList(arrayList);
Unfortunately the read-only constraints won't be enforced by the compiler. They will, however, be enforced at runtime.
You also have available to you: unmodifiableSet, unmodifiableMap, unmodifiableCollection, unmodifiableSortedSet, and unmodifiableSortedMap. And if these are not enough, you can still take inspiration from this general design approach, and create your own custom read-only wrapper classes.
:) You have several options:
Don't expose getter, provide only methods which are allowed to call, e.g.
public void addToList(Object arg) { this.arr.add(arg);}
Return immutable object:
public List getArr() { return Collections.unmodifiableList(this.arr); }
You could also use Google Guava's immutable collections. In this case, you would store an ImmutableList in your field.
Of course, if your class needs to modify this list internally, using ImmutableList might turn out to be a bad idea, since you'll need to create a new ImmutableList instance and reassign it to the field each time...
But it's perfect when you know the List won't change after object construction.
Immutable example (list won't change after object construction)
#Immutable
public final class Foo {
#Nonnull
private final ImmutableList<String> list;
public Foo(#Nonnull List<String> list) {
// you could also compute the appropriate list here
// before assigning it to the field
this.list = ImmutableList.copyOf(list);
}
public ImmutableList<String> getList() {
return list;
}
}
Mutable example (list may only be modified using the setter)
public class Foo {
#Nonnull
private ImmutableList<String> list = ImmutableList.of();
public ImmutableList<String> getList() {
return list;
}
public void setList(#Nonnull List<String> list) {
this.list = ImmutableList.copyOf(list);
}
}
Remarks
I know it's often advised to make methods return the most generic type possible (List in this case), but I prefer to declare my getter's return type as an ImmutableList, because it acts as documentation (no need to document the returned list's immutability in the Javadoc) and as an API contract. It's like saying "I guarantee this list to be immutable, you do not have to worry or defensively copy it". And it is very concise.
ImmutableList.copyOf() is great, since it automatically rejects null lists (by throwing NullPointerException). It also rejects null elements. And it won't copy the source list if it's already an ImmutableList, which avoids useless object instantiation.
In the second example, I initialize the field to an empty ImmutableList using ImmutableList.of(), because it's a good practice to return empty collections instead of null values (Null Object pattern). You might think that this creates needless object instantiation, but ImmutableList.of() actually returns a singleton.
unmodifiableList is definitely the answer.
I'm currently playing with implementing various sorting algorithms in Java, mostly for fun, but I'm struggling with how to do it 'right'. That is, I want the user to be able to call the sorting algorithm of choice on anything that is comparable - ints, longs, Strings, booleans (actually, are these comparable in Java?), their own classes; whatever. The question is how to do this.
I was thinking of using a class to represent the sorting algorithm, and therefore store the things to be sorted inside using a generic list or whatever (List<E>). This would also allow me to use multiple constructors and thus allow the user to pass in the data in various forms - Lists, Arrays, whatever. Is this the correct way to do it? My current problem is that I don't wish for the user to have to create a class when they want to sort something, I'd rather it was able to be called much like System.out.println or the like.
// Example:
int[] myInts = {5,4,3,2,1};
// This is what I do *not* want.
InsertionSort mySort = new InsertionSort();
int[] sortedInts = mySort.sort(myInts);
// This is more like what I want.
int[] sortedInts = Sorting.insertionSort(myInts);
I apologise with what may seem like a basic question, but I am just learning my way with programming languages. Which is a bit ridicolous for a 2nd year Computing student working at a software company for his summer job, but you'd be surprised at how little programming knowledge is required for most of my work... it's usually more design knowledge.
EDIT:
For clarity, my three main question are:
Is it better to have the user create a class to do the sorting, or to have a static method in a class the user imports?
Is it possible to deal with both primitive data types and generic objects easily? Since I want to be able to handle any generic object that implements comparable (or likewise), this then causes problems with primitives (as they don't implement anything ;) ).
What is the best way to handle generic input - what should I check for before I try to sort them (implementing Comparable, for example)?
You could take as example the way Collections provides the binarySearch operation ... And indeed, the
int[] sortedInts = Sorting.insertionSort(myInts);
is more java-way, even if I would personnally prefer
public class Sorting {
public static <DataType extends Comparable> Iterable<DataType> insertionSort(Iterable<DataType> data);
}
<DataType> ensure output data is of the same type than input
Iterable<DataType> data input data is an iterable, to ensure maximum compatibility. Obviously, using a List would be by far simple, as it allows internal item reordering. Howeve"r, using an iterable ensure the implementor of this method will have to re-create the list in order to modify it, guaranteeing that the input list is left unchanged, and that the output list is another one.
Since I just saw you edit your question, let me reply to it point by point (and consider chosing an answer after that, as it is easier to add new questions than to edit existing ones endlessly - unless you make your question a community wiki, like I do of this reply)
Is it better to have the user create a class to do the sorting, or to have a static method in a class the user imports?
To my mind, using a static method in this case is preferable, as you here have to manipulate objects you didn't create, in a quite "basic" fashion.
Is it possible to deal with both primitive data types and generic objects easily? Since I want to be able to handle any generic object that implements Comparable (or likewise), this then causes problems with primitives (as they don't implement anything ;) ).
Have you heard about autoboxing ? It's a feature of Java 5 which makes primary types "equivalents" of objects. That's to say int are automatically converted into Integer, which, as you know, implement Comparable.
What is the best way to handle generic input - what should I check for before I try to sort them (implementing Comparable, for example)?
Notice that, due to my method declaration (the ), checking that input data implements Comparable is not done by you, but by the Jav compiler, allowing your IDE to show you mistakes.
I think you answered your own question? If you want to expose a static method instead of making the user create and object and call an instance method, then just do that. Sorting.insertionSort() looks fine to me.
Internally that can dispatch to whatever you like. Inside, if you want to implement this with classes and polymorphism and whatnot, go ahead. It does seem like a bit overkill though. I am not sure inheritance and polymorphism help a lot here.
The normal way of implementing a sorting algorithm would be to implement a static method, e.g. take a look at the source code for Arrays.sort(). You can overload this method with diferent implementations for different parameter types (e.g. objects that implement comparable vs. provide your own comparator vs. primitive arrays etc.)
Here's one I wrote earlier:
public static <T> void swap(T[] a, int x, int y) {
T t=a[x];
a[x]=a[y];
a[y]=t;
}
public static <T extends Comparable<? super T>> void mergeInOrder(T[] src, T[] dst, int p1, int p2, int p3, int p4) {
if (src[p2].compareTo(src[p3])<=0) return; // already sorted!
// cut away ends
while (src[p1].compareTo(src[p3])<=0) p1++;
while (src[p2].compareTo(src[p4])<=0) p4--;
int i1=p1;
int i3=p3;
int di=p1;
while(di<p4) {
if (src[i1].compareTo(src[i3])<=0) {
dst[di++]=src[i1++];
} else {
dst[di++]=src[i3++];
if (i3>p4) {
System.arraycopy(src,i1,dst,di,p2-i1+1);
break;
}
}
}
System.arraycopy(dst, p1, src, p1, (p4-p1)+1);
}
public static <T extends Comparable<? super T>> void mergeSort(T[] src, T[] dst, int start, int end) {
if (start+1>=end) {
if (start>=end) return;
if (src[start].compareTo(src[end])>0) {
swap(src,start,end);
}
return;
}
int middle=(start+end)/2;
mergeSort(src,dst,start, middle);
mergeSort(src,dst,middle+1, end);
mergeInOrder(src,dst,start,middle,middle+1,end);
}
private static ThreadLocal<Comparable<?>[]> mergeSortTemp=new ThreadLocal<Comparable<?>[]>();
#SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void mergeSort(T[] src) {
int length=src.length;
Comparable<?>[] temp=mergeSortTemp.get();
if ((temp==null)||(temp.length<length)) {
temp=new Comparable[length*3/2];
mergeSortTemp.set(temp);
}
mergeSort(src,(T[])temp,0,length-1);
}
However, I can think of two good reasons to implement a sorting algorithm as a class where you generate your own instance:
It lets you polymorphically pass around instances of sorting algorithms - this could be useful if e.g. you were creating a collection of sorting algorithms and wanted to run lots of benchmarks on them for example.
You can have private state in the sorter instance - this is useful for some sorting algorithms, e.g. having some pre-allocated arrays for temporary storage, and it makes sense to put it in a class instance if you want to be able to simultaneously use different sort instances from multiple threads - a static method implementation would need some form of synchronisation (e.g. see the use of the ThreadLocal in the code above).
I'm not sure if this is what you are struggling with ... but it is next to impossible to implement an algorithm that works both for reference types and (real) primitive types. The reason is the Java type system does not have a notional universal type that has the primitive types and Object as subtypes.
The normal workaround for this is to wrap the primitive types using their corresponding wrapper classes; e.g. Integer for int, Boolean for bool and so on. This allows you to implement (for example) a sorting algorithms that for for any Collection<T> or any <T>[].
This approach has performance / memory usage issues when applied to large arrays of (say) integers. Either you wear the performance hit, or you implement the algorithm and its supporting classes separately for each primitive type.
(I said next to impossible, because it is possible to abstract the comparison of a pair of array elements and swapping of a pair of array elements in a way that doesn't expose the actual element type in the interface; e.g.
public interface ArraySortAdapter {
public abstract int compareElements(Object array, int pos1, int pos2);
public abstract void swapElements(Object array, int pos1, int pos2);
}
and provide different implementations for different array types; e.g.
public class IntArraySortAdapter implements ArraySortAdapter {
public int compareElements(Object array, int pos1, int pos2) {
int[] intArray = (int[]) array;
if (intArray[pos1] < intArray[pos2]) {
return -1;
} else if (intArray[pos1] > intArray[pos2]) {
return +1;
} else {
return 0;
}
}
...
}
However, this is cumbersome and inefficient, to say the least ...)
considering i have a method which gets a List passed as an param. Within this method i want to use for instance an ArrayList specific function on that list (lets say trimToSize()). What would be the general approach to deal with a problem like this ?
Here two example:
First approach (i don't think this is good)
private void doSomething(final List<T> list) {
// ... do something
((ArrayList<T>) list).trimToSize();
// ... do something
}
Second approach (i think this one is better)
private void doSomething2(final List<T> list) {
final List<T> myList = new ArrayList<T>();
// Collections.copy(myList, list); or
myList.addAll(list);
((ArrayList<T>) myList).trimToSize();
//..do something
}
I'm curious whats the best solution for a problem like this.
Well, the preferred option is to just write the method to take an ArrayList in the first place. If you need ArrayList specific functionality, the method has no business taking a List. Transfer the responsibility of ensuring that the parameter is of the right type to the caller and don't fiddle around with it inside the method.
Why not just declare method as a private void doSomething(final ArrayList<T> list), if you want only ArrayList as parameter?
If you're accepting any object implementing the List interface then your function should only invoke methods implemented from the interface.
If you want to invoke functions from ArrayList class then have ArrayList as your parameter. Much safer than either of your options.
The second we have huge overhead with big lists, but is safer. I would go for the first, but with check whether the provided List is ArrayList and then make a cast.
You should have a strong reasons to not take an ArrayList as a parameter though.
The first option you've shown only works for ArrayLists so it's not an option if you want to support any type of List. If you want to support any type of List you must convert (not cast) it to an ArrayList.
I think there might be some confusion because the List and ArrayList are so closely related (by inheritance). It is only coincidence that the parameter type and the class we need to call the function on are related in this way.
If we abstract the requirements a bit:
We need to act on a series of values
We need to use trimToSize() on the
series of values.
If the values were coming as an array there would be no question but to create a new ArrayList with the values from the array and then use trimToSize(), because casting would not be an option. It is just bad luck that the method we need trimToSize() happens to be on a subclass of List, and the author wants to pass the values as a List.
What about
private void doSomething(final List<T> list) {
final ArrayList<T> arrayList;
if (list instanceof ArrayList) {
arrayList = (ArrayList<T>) list;
} else {
arrayList = new ArrayList<T>(list);
}
...
arrayList.trimToSize();
}
Of course, I agree with Chinmay Kanchi: for a private method, it makes no sense to accept a more general type than necessary. My approach is only feasible if it causes no problems to modify the given list.
Your first method changes the List passed to the method while the other one doesn't. Two methods are not comparable.
Since it is a private method, the convention of using the List interface is not overly important. There is no public API affected so use whichever method is the most convenient for its usage in the class.
For example, if 5 other methods call this method with potentially varying types of List, then use your second option and centralize the conversion in 1 method (you can even throw in a check for type and not convert if you like). If your class only deals with ArrayList internally anyway, and you know that is what it will be when called, then declare it as a ArrayList and make your life easy for yourself.