snippetjavaMinor
Custom MultiIterator with type filter
Viewed 0 times
withmultiiteratortypecustomfilter
Problem
I'll start with giving a bit of background as there are many classes involved and I can't attach all of them because that would make this question wildly too long. For the curios they can be found at my github repo.
I have an immutable structure called a
A
In many places in the code base I need to iterate over all items on the
To this end I decided upon letting
Relevant excerpt from
```
public abstract class LoadoutBase {
public Iterable items(){
return new LoadoutIterable(this, null);
}
public Iterable items(Cl
I have an immutable structure called a
Chassis which consists of 8 immutable Components. Each Component is named by a Location such as Location.LeftArm or Location.RightTorso.A
Loadout is a particular configuration of Items that are equipped on a Chassis. For each Component on the Chassis, the Loadout has a matching ConfiguredComponent that contains the Items equipped on that component of the Chassis. In addition to this, each Component can have a number of fixed Items and some Items are kind of fixed but can be toggled on and off (not my decision, that's the game rules). So the toggle state is a part of the ConfiguredComponent which is why ConfiguredComponent has a getItemsFixed() method which will return the truly fixed items + any items which have their toggle state set to enabled.In many places in the code base I need to iterate over all items on the
Loadout (fixed and removable). Even more frequently I'm only interested in certain types of items on the loadout. For example those that are a subclass of Weapon which is an Item or even those items that implement a particular interface not necessarily inheriting from Item. In other words I may want to filter on a class that is not descendant from Item. However all items on the loadout have Item as a base class.To this end I decided upon letting
Loadout have methods to return an Iterable of approriate type which I can use to iterate over Items of a particular type. Then I implement a form of MultiIterator that can iterate over all the Items on the Loadout.Relevant excerpt from
Loadout:```
public abstract class LoadoutBase {
public Iterable items(){
return new LoadoutIterable(this, null);
}
public Iterable items(Cl
Solution
It's too long for the time I can spend now, so just some random comments:
Assuming
by
How can I (if I can) get rid of the unchecked cast?
This is strange:
Firstly, I'd replace
But even this sounds too complicated, given that there's Guava's
I can't see how
Consider implementing
I don't understand the loop, so I can't tell more. Consider using
Assuming
Location is an enum, you can replaceprivate final static Location[] LOCATION_ORDER;
LOCATION_ORDER = new Location[Location.values().length];
for(Location location : Location.values()){
LOCATION_ORDER[location.ordinal()] = location;
}by
private final static Location[] LOCATION_ORDER = Location.values();How can I (if I can) get rid of the unchecked cast?
This is strange:
if( filter == null || filter.isAssignableFrom(item.getClass()) ){
return (T)item; // This cast is checked
}Firstly, I'd replace
null by Object.class for filter. You want everything and everything is an Object. Secondly, the condition can be expressed simpler. Thirdly, there is Class#cast.if (filter.isInstance(item) return filter.cast(item);But even this sounds too complicated, given that there's Guava's
Iterables#filter doing exactly this.I can't see how
getNextNonFiltered can be non-filtered when it uses filter.Consider implementing
Location#next() to move the functionality to where it belongs.I don't understand the loop, so I can't tell more. Consider using
AbstractIterator or extracting methods to make it clearer.Code Snippets
private final static Location[] LOCATION_ORDER;
LOCATION_ORDER = new Location[Location.values().length];
for(Location location : Location.values()){
LOCATION_ORDER[location.ordinal()] = location;
}private final static Location[] LOCATION_ORDER = Location.values();if( filter == null || filter.isAssignableFrom(item.getClass()) ){
return (T)item; // This cast is checked
}if (filter.isInstance(item) return filter.cast(item);Context
StackExchange Code Review Q#61389, answer score: 2
Revisions (0)
No revisions yet.