I am creating a datatype that needs to support two methods:
length(int v, int w)
length(Iterable<Integer> v, Iterable<Integer> w)
the first one is a special case of the second method and I want to reuse the code. How do I efficiently convert an integer into an Iterable object?
So far, I used an ArrayList.
ArrayList<Integer> a = new ArrayList<Integer>(); a.add(v);
ArrayList<Integer> b = new ArrayList<Integer>(); b.add(w);
return length(a,b);
Thanks.
Why do you want to use the same method? I think it is better use two differents methods, this is the purpose of overloading.
When you use the Iterable you have to use autoboxing of java to create Integer and then create the ArrayList, it is worse than use two differents methods, also to let the code more simple to read.
But if you want to use only Iterable I would use this code (to use the less possible code) or #sisyphus code:
length(Arrays.asList(1), Arrays.asList(2));
Merging varargs with ArrayList conversion allows you to create an ArrayList in a cool way.
Here you can see the working code:
code Iterable
Related
I'm wondering if there is a way to easily modify the ".contains()" method in the List interface in Java without creating a custom class. For example:
When dealing with a collection of arrays in java, the .contains() method will always return false because the .contains() method always checks for equality with a generic .equals() call from the Object class that only returns true if the compared objects have the same reference in memory. However, with arrays, it is much more useful to do an Arrays.equals() check on the two arrays.
Code:
public class Temp {
public static void main(String[] args) {
int[] myIntArray = new int[] {1, 2, 3};
List<int[]> myList = new ArrayList<>();
myList.add(myIntArray);
System.out.println(myList.contains(new int[] {1, 2, 3}));
} // Output in the console: false
// Preferred output: true
}
I understand that it is possible to do this rather easily by using a for loop and iterating over the whole list using the Arrays.equals() method, but the goal for me is to learn how to easily sculpt the .contains() method into what I need for future use. Thanks a lot!
No. contains() can't do anything other than use Object.equals, because that's required by the specification.
That's not to say that it's not reasonable to want a notion of contains for an array; merely that you can't overload the existing concept.
You can straightforwardly create a static method:
static <T> boolean containsArray(List<? extends T[]> list, T[] query) {
return list.stream().anyMatch(e -> Arrays.equals(e, query));
}
And then invoke this where you would otherwise invoke list.contains(query).
This has the advantage that it works for any list (with reference-typed array elements): you don't have to create it specially, merely update these specialized comparisons.
(The above would work for any reference-typed array. You'd need to specialize it for primitive-typed arrays).
It also has the advantage that you don't have to deal with the thorny consequences highlighted by Stephen C (e.g. how indexOf, remove etc work).
There's another alternative: use a list element type which supports equals "correctly". For example, you can wrap arrays using Arrays.asList to store them in the list, so you have a List<List<T>> instead of List<T[]>.
This would be quite an invasive change: it would require changing the type of the list throughout your code; you've not provided any indication of how pervasively-used your list of arrays is.
I am wondering if there is a way to easily modify the contains method in the List interface in Java without creating a custom class.
There isn't a way. The contains method of the standard implementations of List behave as specified by the List API; i.e. they use the equals method.
The flip-side that it would not be hard to extend the ArrayList class and override contains to do what you want. But if you are doing it properly, you need to consider whether you want:
indexOf and lastIndexOf to be consistent with contains
the semantics of equals(Object) to be consistent with it
the semantics of a list returned by sublist(int, int) to be consistent with the semantics of the main list.
I have a class which always holds four objects:
class Foo<E> {
Cow<E> a, b, c, d;
}
I want to be able to iterate over them, so ideally I'd like to use an array:
class Foo<E> {
Cow<E>[] cows = new Cow<E>[4]; // won't work, can't create generic array
}
I don't want to use a list or a set since I want there to always be 4 Cow objects. What's the best solution for me?
If you want to preserve the genericity, you will have to reimplement something similar to a list and I don't think it is worth it.
You said:
The first is that you can add and remove elements to and from a list.
Well you can create an unmodifiable list:
List<E> list = Collections.unmodifiableList(Arrays.asList(a, b, c, d));
The second is that I'm creating a quadtree data structure and using a list wouldn't be too good for performance. Quadtrees have a lot of quadrants and using lists would decrease performance significantly.
First you can initialise the list to the right size:
List<E> list = new ArrayList<>(4);
Once you have done that, the list will only use a little bit more memory than an array (probably 8 bytes: 4 byte for the backing array reference and another 4 byte for the size).
And in terms of performance an ArrayList performs almost as good as an array.
Bottom line: I would start by using a list and measure the performance. If it is not good enough AND it is due to using a list instead of an array, then you will have to adapt your design - but I doubt that this will be your main issue.
Use a generic ArrayList and simply have methods to insert values into your object, and do checks inside those methods, to make sure you don't end up having more than 4 Cow objects.
I will suggest creating a bounded list. Java does not have an inbuilt one however you can create a custom one using Google collections or use the one in Apache collections. See Is there a bounded non-blocking Collection in Java?
Use Collection instead of array:
List<Cow<E>> cows = new ArrayList<>(); // in Java 7
Or
List<Cow<E>> cows = new ArrayList<Cow<E>>(); //Java 6 and below
More information will show why it is IMPOSSIBLE to have arrays whit generics. You can see here
Cow<E>[] cows = (Cow<E>[])new Cow[4];
or
Cow<E>[] cows = (Cow<E>[])new Cow<?>[4];
This question already has answers here:
Equivalent of std::vector in Java?
(9 answers)
Closed 9 years ago.
I'm using Java programming language.
C++ has vector<T> and I need the equivalent vector in Java.
I want to convert this code to Java.
Vector<T> a[Maxn]; // Example: string, int, myclass, myvar, ...
int n;
cin >> n;
for(int i=0; i<n; i++)
{
T x, y;
cin >> x >> y;
x--, y--;
v[x].push_back(y);
}
You are probably looking for ArrayList
Resizable-array implementation of the List interface. Implements all
optional list operations, and permits all elements, including null. In
addition to implementing the List interface, this class provides
methods to manipulate the size of the array that is used internally to
store the list.
Something like this:
ArrayList ar = new ArrayList<String>();
ar.add("abc");
You can use List<T>, Java has many better ways, take it easy!
you could Search it...
Have a look at java.util.List. There are many concrete implementations of list including java.util.ArrayList
Here is an example using ArrayList
Note Java Collections e.g. List<T> make use of generics. Below I am using a list of String
List<String> list = new ArrayList<String>();
list.add("some string");
I'm pretty sure that this is the class you are looking for:
java.util.List
If you want something analogous to C++'s std::vector, I would start by looking at the various classes that implement the List interface (http://docs.oracle.com/javase/7/docs/api/java/util/List.html).
Probably the most commonly-used List is ArrayList, which has all the normal operations you would expect - add, get, size, iterator, etc.
Alternatively there is LinkedList, which is useful in its own way, depending on what exactly you're trying to achieve.
EDIT: I do not advocate using java.util.Vector<E>, but since you are coming from a C background, it might give you a warm fuzzy to use the same name. However, you should note (from the Java API)
Unlike the new collection implementations, Vector is synchronized. If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector.
So it's best to use some other implementation of java.util.List<E> -- most common to use java.util.ArrayList<E>
What would be the simplest way to convert List<Integer> to List<String> objects. Currently I iterate through all the integers and add them to a List<String> objects, is there a utility function which is already available?
You found a simple way. The type are "incompatible", so you need a conversion rule anyway (which is simple in your case). The algorithm will always be O(n), regardless of iterating through the collections manually or calling some API method from some 3rd party library (JRE doesn't offer API for your task).
While there are some libraries that can do general List transformations (like Google's Guava) using one for this case probably won't save you any lines of code as you'd need to create a Function object, and that alone involves so much boilerplate that your existing code is probably smaller.
I don't think we have a utility function for this task. Even there exist a utility function for this, it might have to iterate the List<Integer>
Do you have to have a List structure? Why not do a Map<Integer, String>, and when an integer is inserted, a String value of that integer can be created.
I don't think there is an automatic way to do this, simply because of the way Java compiles Generic arguments (called type erasure, a complicated way of saying "Haha, we're actually saving only Object references and the compiler inserts casts to the generic argument every time you do a get()" ).
Why do you have to convert it to a list of Strings? Isn't it just the same to every time you need a list of strings to just iterate through the list of Integers and call toString() on each one?
EDIT:
either way, here's a solution that will work:
public static List<String> convToString(List<Integer> list){
List<String> ret = new ArrayList<String>();
for (Integer i : list){
ret.add(i.toString());
}
return ret;
}
And back again !
public static List<Integer> convToInteger(List<String> list){
List<Integer> ret = new ArrayList<Integer>();
for (String s : list){
ret.add(Integer.parseInt(s));
}
return ret;
}
I am new to java, I have seen in the code at many places where my seniors have declared as
List myList = new ArrayList(); (option1)
Instead of
ArrayList myList = new ArrayList(); (option2)
Can you please tell me why people use Option1, is there any advantages?
If we use option2, do we miss out any advantages or features?
Option 1 is considered programming to an interface, where option 2 is programming to an implementation. The latter is sometimes necessary, but the former provides you with the ability to easily switch implementations by ensuring that you don't depend on methods provided by a particular implementation.
Furthermore, if you create methods that need only the functionality provided by an interface then they should be declared as requiring the interface so that any object implementing the interface can be passed to them. Doing so broadens the scope for re-use of the API. For example:
// This can be called passing any List
public int countItems(List lst, Filter flt) {
// iterate list, apply filter, and count matching objects
}
// This can called passing only an ArrayList, an unnecessary limitation in this case
public int countItems(ArrayList lst, Filter flt) {
// iterate list, apply filter, and count matching objects
}
That said, for some interfaces, there are hidden implementation dependent traps (at least in Java). An example of this in List.get(int); if you have an ArrayList this is efficient, but for a LinkedList it is not. If the list is very large the difference can be dramatic, esp for a poorly conceived construct like this loop:
for(int xa=0,len=list.length; xa<len; xa++) {
Object obj=list.get(xa);
obj.doSomething();
}
which has terrible performance for large linked lists since the list must be traversed from the beginning for every get(xa).
The advantage of using option1, ie, List myList = new ArrayList(); is to have polymorphic behaviour with respect to methods. Say, for example, you can have a method which takes arguments of type List,
someMethod(List lst)
{
lst.doSomething();
//do somethng else.....
}
In this method lst can be of type Linked List, ArrayList or CopyOnWriteArrayList.