In C#, finding an item in an ArrayList that have a certain property, it's quite easy:
mSelectedBoard = mBoardConnections.FirstOrDefault(bcd => bcd.Id == id);
This is the easiest I've found to do the same in Java (wish I could afford MonoTouch for android):
for ( BoardConnectionData bcd : mBoardConnections ) {
if (bcd.getID() == id) {
mSelectedBoard = bcd;
break;
}
}
Am I missing an easier way to do this?
Thanks!
Define a meaningful equals and use Collection.contains.
There are a number of utility libraries that contain implementations using various "am I it?" implementations. (Guava, Commons Collections, etc.)
Another option is to create a typed collection containing utility methods finding elements by arbitrary criteria.
In any case, the code snippet shown shouldn't live in the mainline code, it should be abstracted into its own method, regardless of where it ends up living.
Since there are no closures in Java, there's no really easier way to do it. Of course, you can use Guava, but IMHO it offers only a bit of conciseness for a lot of complexity (for your example, at last, because Guava is quite cool otherwise)
Assuming BoardConnectionData class correctly overrides the equals method based on the ID, the following should tell you if the object is in the list or not:
mBoardConnections.contains(object);
If you inherit from Comparable to test for the id member and use a SortedSet:
BoardConnectionData brd =
sortedSet.tailSet(new BoardConnectionData(searchedId)).first();
It is not more efficient complexity-wise, but it is shorter code. :)
To pile on to Dave Newton's answer. The Collection is an ArrayList, so with an appropriate equals (plus hashCode) implementation on BoardConnectionData, the indexOf method would allow the expression
selectedBoard = boardConnections.getAt(boardConnections.indexOf(new BoardConnectionData(id)))
Of course, it's likely preferable to construct a probe object rather than creating a full-blown instance from only the id.
You really should ask your self if ArrayList is the right data structure. Given similar task, I would choose a Map. Both C# and Java will need O(N) to search in an array. Using a map is O(1). If this is something you need to often then I would suggest the right structure.
Really the only difference between the C# and Java version is that one is shorter and uses closure. As many other people have suggested, you can do the same thing with some existing libraries. No one actually showed any code though. With Guava, you can do:
Iterables.find(new Predicate<Data>(){
public boolean apply(Data d){
return d.id == someId;
)}, list);
Or if you want a default value you can use .find(predicate, list, defaultValue).
If you need to match a single property, and multiple items in the list can have identical values for that property, then you need to loop thru like you are doing. Java has a Collections utility class with a bunch of static methods; it might make sense for you to define your own collections utility methods to handle cases like this.
In general though, if you wan't to find an element, just use indexOf and be sure to implement equals properly.
In Java 8 you can do like this:
mSelectedBoard = mBoardConnections
.stream().filter(bcd -> bcd.Id == id).findFirst().orElse(null);
Related
In my situation, given an enum, check if that enum belongs to a specific list of enums or not.
My solution is putting all of the enums that I want to compare to the given enum to an ArrayList. So I can use contains(..) method of the ArrayList to do the checking task.
PokemonEnums givenPokemon = ...;
ArrayList<PokemonEnums> AshPokemonList = ...;
while(doing something){
if(AshPokemonList.contains(givenPokemon){
//do fun stuffs
}
}
Is it acceptable in term of performance or is there any other way I can do this in a more elegant way?
P/S: Although I know that AshPokemonList will probably not contain more 10, I can use if with multiple checks, but then it looks quite messy to me. But I don't know in term of performance, will it be better?
Java provides a special container called EnumSet<T> which is optimized for working with enums:
PokemonEnums givenPokemon = ...;
EnumSet<PokemonEnums> ashPokemonSet = ...;
while(doing something){
if(ashPokemonSet.contains(givenPokemon) {
//do fun stuffs
}
}
This implementation should be better than an array list, because it employs bit vectors internally:
Enum sets are represented internally as bit vectors. This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags."
No, it is not "acceptable", because this has linear complexity, so the run time depends on the length of the list.
Use an EnumSet instead. This class is not sorted, but you can check in constant time whether an enum is contained, no matter how big the set is.
Please use EnumSet: https://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html. It is something specially created for Enums. Space as well as performance-wise, it is very good.
Copy-pasting from the API:
A specialized Set implementation for use with enum types. All of the
elements in an enum set must come from a single enum type that is
specified, explicitly or implicitly, when the set is created. Enum
sets are represented internally as bit vectors. This representation is
extremely compact and efficient. The space and time performance of
this class should be good enough to allow its use as a high-quality,
typesafe alternative to traditional int-based "bit flags." Even bulk
operations (such as containsAll and retainAll) should run very quickly
if their argument is also an enum set.
I've been looking at a lot of code recently (for my own benefit, as I'm still learning to program), and I've noticed a number of Java projects (from what appear to be well respected programmers) wherein they use some sort of immediate down-casting.
I actually have multiple examples, but here's one that I pulled straight from the code:
public Set<Coordinates> neighboringCoordinates() {
HashSet<Coordinates> neighbors = new HashSet<Coordinates>();
neighbors.add(getNorthWest());
neighbors.add(getNorth());
neighbors.add(getNorthEast());
neighbors.add(getWest());
neighbors.add(getEast());
neighbors.add(getSouthEast());
neighbors.add(getSouth());
neighbors.add(getSouthWest());
return neighbors;
}
And from the same project, here's another (perhaps more concise) example:
private Set<Coordinates> liveCellCoordinates = new HashSet<Coordinates>();
In the first example, you can see that the method has a return type of Set<Coordinates> - however, that specific method will always only return a HashSet - and no other type of Set.
In the second example, liveCellCoordinates is initially defined as a Set<Coordinates>, but is immediately turned into a HashSet.
And it's not just this single, specific project - I've found this to be the case in multiple projects.
I am curious as to what the logic is behind this? Is there some code-conventions that would consider this good practice? Does it make the program faster or more efficient somehow? What benefit would it have?
When you are designing a method signature, it is usually better to only pin down what needs to be pinned down. In the first example, by specifying only that the method returns a Set (instead of a HashSet specifically), the implementer is free to change the implementation if it turns out that a HashSet is not the right data structure. If the method had been declared to return a HashSet, then all code that depended on the object being specifically a HashSet instead of the more general Set type would also need to be revised.
A realistic example would be if it was decided that neighboringCoordinates() needed to return a thread-safe Set object. As written, this would be very simple to do—replace the last line of the method with:
return Collections.synchronizedSet(neighbors);
As it turns out, the Set object returned by synchronizedSet() is not assignment-compatible with HashSet. Good thing the method was declared to return a Set!
A similar consideration applies to the second case. Code in the class that uses liveCellCoordinates shouldn't need to know anything more than that it is a Set. (In fact, in the first example, I would have expected to see:
Set<Coordinates> neighbors = new HashSet<Coordinates>();
at the top of the method.)
Because now if they change the type in the future, any code depending on neighboringCoordinates does not have to be updated.
Let's you had:
HashedSet<Coordinates> c = neighboringCoordinates()
Now, let's say they change their code to use a different implementation of set. Guess what, you have to change your code too.
But, if you have:
Set<Coordinates> c = neighboringCoordinates()
As long as their collection still implements set, they can change whatever they want internally without affecting your code.
Basically, it's just being the least specific possible (within reason) for the sake of hiding internal details. Your code only cares that it can access the collection as a set. It doesn't care what specific type of set it is, if that makes sense. Thus, why make your code be coupled to a HashedSet?
In the first example, that the method will always only return a HashSet is an implementation detail that users of the class should not have to know. This frees the developer to use a different implementation if it is desirable.
The design principle in play here is "always prefer specifying abstract types".
Set is abstract; there is no such concrete class Set - it's an interface, which is by definition abstract. The method's contract is to return a Set - it's up the developer to chose what kind of Set to return.
You should do this with fields as well, eg:
private List<String> names = new ArrayList<String>;
not
private ArrayList<String> names = new ArrayList<String>;
Later, you may want to change to using a LinkedList - specifying the abstract type allows you to do this with no code changes (except for the initializtion of course).
The question is how you want to use the variable. e.g. is it in your context important that it is a HashSet? If not, you should say what you need, and this is just a Set.
Things were different if you would use e.g. TreeSet here. Then you would lose the information that the Set is sorted, and if your algorithm relies on this property, changing the implementation to HashSet would be a disaster. In this case the best solution would be to write SortedSet<Coordinates> set = new TreeSet<Coordinates>();. Or imagine you would write List<String> list = new LinkedList<String>();: That's ok if you want to use list just as list, but you wouldn't be able to use the LinkedList as deque any longer, as methods like offerFirst or peekLast are not on the List interface.
So the general rule is: Be as general as possible, but as specific as needed. Ask yourself what you really need. Does a certain interface provide all functionality and promises you need? If yes, then use it. Else be more specific, use another interface or the class itself as type.
Here is another reason. It's because more general (abstract) types have fewer behaviors which is good because there is less room to mess up.
For example, let's say you implemented a method like this: List<User> users = getUsers(); when in fact you could have used a more abstract type like this: Collection<User> users = getUsers();. Now Bob might assume wrongly that your method returns users in alphabetic order and create a bug. Had you used Collection, there wouldn't have been such confusion.
It's quite simple.
In your example, the method returns Set. From an API designer's point of view this has one significant advantage, compared to returning HashSet.
If at some point, the programmer decides to use SuperPerformantSetForDirections then he can do it without changing the public API, if the new class extends Set.
The trick is "code to the interface".
The reason for this is that in 99.9% of the cases you just want the behavior from HashSet/TreeSet/WhateverSet that conforms to the Set-interface implemented by all of them. It keeps your code simpler, and the only reason you actually need to say HashSet is to specify what behavior the Set you need has.
As you may know HashSet is relatively fast but returns items in seemingly random order. TreeSet is a bit slower, but returns items in alphabetical order. Your code does not care, as long as it behaves like a Set.
This gives simpler code, easier to work with.
Note that the typical choices for a Set is a HashSet, Map is HashMap and List is ArrayList. If you use a non-typical (for you) implementation, there should be a good reason for it (like, needing the alphabetical sorting) and that reason should be put in a comment next to the new statement. Makes the life easier for future maintainers.
I would like to know your opinions on which you find is a better approach to have a list filled up by a different method. I know there isn't a definite answer, but I would like to see reasonable pros and cons.
Approach 1.
private List<Snap> snapList;
snapList = getSnapList();
Approach 2.
private List<Snap> snapList = new ArrayList<Snap>();
fillSnapList(snapList);
Thanks,
Matyas
Why not follow the Java API's Collections class and make your fill methods static (if it makes sense and is independent of object state).
Collections.fill( mylist, 0 );
like
MyListFiller.fill( myList, args );
At any rate, creating a filler interface makes sense if the fill method plans to change. If you're not really "filling", but returning object state of some kind, just have the given method build the List and return it.
public List<Object> getMyStuff()
{
//build and return my stuff
}
It depends on the situation.
A method like getSnapList() is appropriate in situations like the following:
The method you're writing doesn't want to care about where the list came from.
The method shouldn't know what kind of list it's getting - for example, if you want to change to using a LinkedList, then you can do it in getSnapList() instead of all the methods that call fillSnapList().
You will only ever want to fill new lists.
A method like fillSnapList() is appropriate in situations like the following:
You may want to fill the list more than one time.
You may want to vary the way the list is filled (i.e. what gets put into it).
You need to fill a list that someone else hands you.
You need to share the list among more than one class or object, and you might need to refill it at some point in its lifespan.
I like approach 1 better than approach 2, because the list is really the output of the method that you're calling. Approach 1 makes that more clear than approach 2.
Also, approach 1 gives the method the opportunity to return an unmodifyable list. You might want this if the list should be filled once and shouldn't be modified later.
Java is not a functional programming language, but the first approach is more in the functional programming style than the second approach (in functional programming, immutability and avoiding mutable state are important ideas - and one important advantage of those is that they make concurrent programming easier, which is also useful in a non-functional programming language).
One con for the first option is that the method name you have choosen (getSnapList()) is often considered a simple accessor, ie return the reference for the field snapList. In your design, it is implied that you will be creating the list if it doesnt exist and filling it with data, which would be introducing a side effect to the normal idiom.
Due to this and as it is better to be explicit, I prefer the second option.
I prefer approach #1 because the method can be overridden by a sub class that would want to use a different List implementation. Also, I think that naming a factory method as a getter is confusing, I would rather name it newSnapList() or createSnapList().
I'm learning PHP5 (last time I checked PHP was in PHP4 days) and I'm glad to see that PHP5 OO is more Java-alike than the PHP4 one but there's still an issue that makes me feel quite unconfortable because of my Java background : ARRAYS.
I'm reading "Proffesional PHP6" (Wrox) and It shows its own Collection implementation.
I've found other clases like the one in http://aheimlich.dreamhosters.com/generic-collections/Collection.phps based on SPL.
I've also found that there's some kind of Collection in SPL (ArrayObject)
However, I'm surprised because I don't really see people using Collections in PHP, they seem to prefer arrays.
So, isn't it a good idea using Collections in PHP just like people use ArrayList instead of basic arrays in Java? After all, php arrays aren't really like java arrays.
Collections in Java make a lot of sense since it's a strongly typed language. It makes sense to have a collection of say "Cars" and another of "Motorbikes".
However, in PHP, due to the dynamically typed nature, it is quite common to sacrifice the formality of Collections. Arrays are sufficient to be used as generic containers of various object types (Cars, Motorbikes, etc.). Also, the added benefit comes from the fact that arrays can be mutated very easily (which sometimes can be a big disadvantage when proper error checking is absent).
I come from a Java background, and I've found that using a Collections design pattern in PHP does not buy much in the way of advantages (no multi-threading, no optimization of memory allocation, no iterators, etc.).
If you're looking for any of those advantages, its probably better to construct a wrapper class around the array, implementing each feature (iterators, etc.) a la carte.
I am very pro collection objects in PHP, they can be used to add type safety, impliment easy to use search, sort and manipulation functionality, and represent the correct OO approach rather then using arrays and the multitude of useful but procedual functions that operate on them in differing patterns all over the source.
We have various collections that we use for various purposes all neatly inherited promoting type safety, consistent coding standards and a high level of code reuse.
But ultimatley, they are all array's internally!
I suppose really it comes down to choice, but in my object oriented world I like to keep easily repeatable segments of code such as sort and search algorithms in base classes, and I find the object notation more self documenting.
PHP arrays are associative... They're far more powerful than Java's arrays, and include much of the functionality of List<> and Map<>.
What do you mean by "good idea"? They're different tools, using one language in the way you used another usually results in frustration.
I, too, was somewhat dismayed to find no Collection type classes in PHP. Arrays have a couple of real disadvantages in my experience.
First, the number of functions available to manipulate them is somewhat limited. For example, I need to be able to arbitrarily insert and remove items to/from a Collection at a given index position. Doing that with the built-in language functions for arrays in PHP is painful at best.
Second, as a sort of offshoot of the first point, writing clean, readable code that manipulates arrays at any level of complexity beyond simple push/pop and iterator stuff is difficult at best. I often find that I have to use one array to index and keep track of another array in data-intensive apps I create.
I prefer working in a framework (my personal choice is NOLOH). There, I have a real Collection class called ArrayList that has functions such as Add, Insert, RemoveAt, RemoveRange and Toggle. I imagine other PHP frameworks address this issue as well.
A nice implementation of collection in php is provided by Varien Lib, this library is part of Magento code with OSL license. ( more info about Magento license and code reuse here.
Cannot find any source code for the library so the best way is to download magento and then look in /lib/Varien/
Yii has implementation of full java like collections stack
http://www.yiiframework.com/doc/api/1.1/CList
I sometimes use this really simple implementation to give me a rough and ready collection.
Normally the main requirement of a collection is enforcing a group of one type of object, you just have to setup a basic class with a constructor to implement it.
class SomeObjectCollection {
/**
* #var SomeObject[]
*/
private $collection = array();
/**
* #param SomeObject $object1
* #param SomeObject $_ [optional]
*/
function __construct(SomeObject $object1 = null, SomeObject $_ = null)
{
foreach (func_get_args() as $index => $arg) {
if(! $arg instanceof SomeObject) throw new \RuntimeException('All arguments must be of type SomeObject');
$this->collection[] = $arg;
}
}
/**
* #return SomeObject[]
*/
public function getAll()
{
return $this->collection;
}
}
Personally, I find the range of functionality provided by java.util.Iterator to be fairly pathetic. At a minimum, I'd like to have methods such as:
peek() returns next element without moving the iterator forward
previous() returns the previous element
Though there are lots of other possibilities such as first() and last().
Does anyone know if such a 3rd party iterator exists? It would probably need to be implemented as a decorator of java.util.Iterator so that it can work with the existing java collections. Ideally, it should be "generics aware".
Thanks in advance,
Don
You can get previous() easily by just using a java.util.ListIterator.
Peek at that point is easily implemented by doing a
public <T> T peek(ListIterator<T> iter) throws NoSuchElementException {
T obj = iter.next();
iter.previous();
return obj;
}
Unfortunately it will be easier to have it as a utility method since each collection class implements their own iterators. To do a wrapper to get a peek method on each collection on some interface such as MyListIterator would be quite a lot of work.
Apache Commons Collections
Google Collections
I think the reason these aren't implemented is because they are non-trivial for some collections and would have large performance impact. I think it would be pretty simple for you to make this work for the collections you care about.
I also don't like that Java iterators have no way of getting the current value without moving it (and therefore you can't easily write code that branches based on the value, just passing the iterator -- you have to pass the value you now have as well).
There is a good damn reason the generic operators do not implement these features: they do not exist for all container. The typical example is a container representing some external data input, like a file seen as a stream. Each time you read a value you consume it and move the pointer forward, if you want it or not. If you impose these constraints on the generic iterators, then you loose the genericity of the iterators.
If you want a previous method, as suggested, use the ListIterator<>, which is then restricted to container behaving as lists.
One thing I would look at is the Seq implementation in clojure
http://clojure.org/sequences
The implementation of the base classes are in Java and full source is available. Seqs are decorators on java iterators (take and implement java iterator interfaces) -- but they also provide their own interface which might be more of what you want -- or at least a starting point.
I saw that someone linked to Google Collections, but no one mentioned that the method you are looking for is called Iterators.peekingIterator().
Still, it would be best if you could just use a ListIterator.
As ykaganovich suggested, you might want to check out the google-collections stuff. There is definitely some support for some of the things you want, like peeking. Also, as some others have mentioned, implementing all of these things for all collections can be dangerous from a possibility or performance viewpoint.
public class Iterazor<T> {
private Iterator<T> it;
public T top;
public Iterazor(Collection<T> co) {
this.it = co.iterator();
top = it.hasNext()? it.next(): null;
}
public void advance() {
top = it.hasNext()? it.next(): null;
}
}
// usage
for(Iterazor<MyObject> iz = new Iterazor<MyObject>(MyCollection);
iz.top!=null; iz.advance())
iz.top.doStuff();
}
I haven't ever run into an issue where I've needed a peek(); Iterator has worked just fine for me. I'm curious how you're using iterators that you feel you need this added functionality.
It sounds like you might be better off using a Stack.
The Java collections were written to provide a minimal set of useful functionality. This is a very good approach for code that has to be implemented by anyone implementing Java. Bloating an interface with functionality that might be useful can lead to a sizable increase in volume of code with improvements noticed only by a few. If peek() and previous() were part of the standard iterator that means everyone writing a new kind of Collection must implement it, whether it's sensible or not.
Iterators are also designed to work on things that physically cannot go backwards, making peek() and previous() both impossible.