Java ArrayList subclass extraction - java

I'm creating an application where I use genetic algorithm (not implemented yet) to make creatures follow food and avoid obstacles.
I have in my simulation class (where the magic happens) an arraylist where all the creatures are stored. To be noted the arraylist is full of abstract class objects whereas my creatures are all a subclass of Creature.
My question is: how can I make another ArrayList or similar where i can iterate over the arraylist and extract a particular subclass? I had a look and it seems there is no way for me to do so because of how java Collections work. Is there any kind of workaround or some library that could make this possible for me?
It is important for me to have separate lists because I need to apply behaviours to different kind of creature and weigh them according to the "dna" of the creature.
GitHub repository for the whole project: https://github.com/Jamesinvi/Animosity/tree/master/Animosity
I tried this but I get a list of all creatures because they are all of the Creature class
//in PSEUDOCODE i would like to do this:
new ArrayList newlist=new ArrayList<Creature>();
for(Creature old:oldList){
if (old instanceof CreatureSubclass){
newlist.add(old);
}
}
Disclaimer: I am a student so forgive me if this is kind of a stupid question but I am struggling a bit with this. Thanks for the help :)
ArrayList <Creature>oldlist=new ArrayList<Creature>();
ArrayList <Creature>newlist=new ArrayList<Creature>();
for(int i=0;i<oldlist.size();i++){
if (oldlist.get(i) instanceof CreatureSubclass){
newlist.add(oldlist.get(i));
}
}

Totally agree with OldCurmudgeon. You should not extract the subclass.
If you really want to do that, one ugly method is to add a string as a member variable to Creature class called flag. So you could use the string comparison instead of instance of which is very dangerous.
if (oldCreature.flag.equals("SmallCreature"))
{
newList.add(oldCreature); // another possible error: do you need a new copy or just reference?
}
And you could consider use enum class instead of string, which would also be a feasible and simple solution.
public enum CreatureName{SmallCreature, LargeCreature}
And again if you want to apply different behaviors onto the different kinds of the subclass (dna), do you have ever considered the design patterns like strategy or abstract class? The visitor pattern may be a good one mentioned by JB Nizet. But it may be overkill for this question.

Related

What are the benefits of declaring a different type than the initialization object due to polymorphism?

Given the following code:
class Vehicle{
public void operate(){
System.out.println("The vehicle is being operated.");
}
}
class Car extends Vehicle{
public void operate(){
System.out.println("The car is being operated.");
}
}
public class Simulation{
public static void main(String[] args){
Vehicle vehicle1 = new Car();
Vehicle vehicle2 = new Vehicle();
vehicle1.operate();
vehicle2.operate();
}
}
What is the benefit of declaring vehicle1 as a Vehicle when we end up initializing it as Car? Shouldn't we just declare it as a Car?
In this example it's not obvious to see the benefit. However, doing so has these benefits:
Usually you'll be calling methods with your object. So we have two options ...myFunction(Vehicle vehicle) or myFunction(Car car). If you choose to use Car, you are restricting the type that can be passed to that method. This is very important. Keep in mind software changes a lot, requirements change, enhancements are made. Let's suppose now you have a shiny new object a Ferrari which extends Vehicle, you cannot call myFunction(Car car) but you will be able to call myFunction(Vehicle vehicle) by passing Ferrari. So in order to make your call using myFunction you will have to change the function signature. Sometimes you cannot change the function signature because, well, it is a library and you don't have the source code. Or maybe you can change it but if you do you will break people using your code. In larger software development, teams are split and you have to create some classes that others will use to complete the whole project. Or you will create libraries and ship to clients. That's the main reason there is polymorphism: to make it easy for many teams to work together without breaking each others code and also improve on the code by using subclasses without breaking things.
When you are writing only a small piece of code that you are not going to share with anyone and don't plan on expanding that code base, there is not much of a benefit. However it is a good habit to have.
Intent: by declaring it as Vehicle, you are showing in your code that you only care about something that has the behavior of a Vehicle .i.e you can call operate(). When you extend a class you can add additional behaviors/methods to it. By declaring it as Vehicle you won't be able to call any of new methods in Car. Remember that your code will most likely be read by others (if it's not your sole property), so using Vehicle makes it obvious that you only care about something that can operate().
Collections: Very often you need to create objects and use them as a collection. Let's imagine you have a race of Vehicles. To make all the Vehicles start, you can easily use Vehicle[] and stuff all of them in there if you use Vehicle. If you were using the Car, Ferrari, Van... you could only stuff them if you use Object[] and then you will have to cast to ((Vehicle)arrayElement).operate() instead of just arrayElement.operate(). I'm giving a simplistic example but I think you'll get the idea.
So to conclude, from only your code there is on the surface no direct benefit but from the reasons above there will be a benefit if you use Vehicle and there is benefit to do so now because you will build good habits and think more OOP and about the bigger picture.
Declaring it locally in a method like that there isn't much difference. Generally speaking you get more flexibility by working on references of the most abstract type that can possibly work. You might see that in code like List<String> foo = new ArrayList<>(); because List is enough.
For example look at Collections.sort(). It takes a List because list elements are ordered. It can't just take Collection because collections aren't guaranteed to be ordered, like Set. But it can use any implementation of List, like ArrayList, LinkedList, etc because ordering is the only property sort() cares about.

Use Scala Case Objects for Java Enums?

Let's say I have the following object:
object CaseObjs {
trait Person
case object Female extends Person
case object Male extends Person
}
For purposes of Don't Repeat Yourself, I'd like to use these CaseObjs.Male and .Female as an Enum-like data structure in Java.
In other words, I'd like to use these case object's in Java rather than create a new Java enum that duplicates code.
Can I do this?
Short answer: No. See also this question
According to this old post on scala-lang the best way to achieve interoperability is to declare the enum in Java. I haven't found any reason to believe that has changed since then.
Using the different Scala variants will make your Java code look bad, and using Java enums from Scala is straight forward.
You mean you want to index out all children of a sealed class? Then I think this post will help you. Make sure that the implementation assumes that all the children of the class are directly-inheriting case objects. Also scala.Enumeration can be used if those children need not specific implementation.

How to create an array of the methods of a class in Java

Good day.
I have a class that I’m going to use to generate math exercises for training purposes. The class is made of a series of method, each one of them generates one type of exercises.
I’d like then to make a method that generates one random exercise of a random type. To do this I thought to store the methods name in an array an call a random entry.
So far so good.
Since in the future I’m going to add methods to generate new exercise types, I’d like to know if there is a way to generate dynamically the array of the methods: once the class is loaded, the constructor will check the methods available and store their name in an array.
Is that possible? And, if so, how?
You can use reflection to discover class' methods.
However in my opinion, it's a bad architecture. Better way to handle different exercises is creating an interface IExercise that will be implemented by *Exercise classes. Then create those objects, put them into an array and pick one randomely. Then call specified method from interface or something...
Instead of storing the names you can store Method proxies
Method[] methods = getClass().getDeclaredMethods();
You need to go through these are ignore any method you add which are not tests.
I highy recomend looking up a Strategy Pattern:
http://en.wikipedia.org/wiki/Strategy_pattern
How would you apply it to your problem? Just create objects that imlement common interfaces (one that gives you method for creating the exercise) and use List of this objects.
You will also practice a very useful pattern!
You can use Reflection API to check Available methods using
Method[] methods= Class.forName("ClassTo test").getDeclaredMethods();
Having said that there are so many things can go wrong while invoking a method.
You can avoid it by just having
interface IExercise
{
void createExercise();
}
class Exercise1 implements IExercise
{
#Override
public void createExercise()
{
}
}
And then you can use IExercise[] to generate Exercise Randomly.
I think you are safer by using the Command pattern and storing each exercise as a command class implementing a marker interface (ICommand). Afterwards you can use reflection to detect at run-time all classes that implement ICommand on the classpath to have a list of exercises you can run. This would also save you from having to add every new type of exercise you design in a collection in your random selection code.
http://en.wikipedia.org/wiki/Command_pattern
This is somewhat similar to the Strategy pattern suggested below.
Create objects like:
MathExample math = new MathExample();
And add them to ArrayList<Objects>
I think, it is better to create chain of responsibility and stroe commands in array. Randomly choose command and put to the chain.

How to restrict elements of an ArrayList without using generics

Suppose I have an Employee class. How can I implement an ArrayList only containing Employee elements without using generics? That is, without Arraylist<Employee>, how can I restrict the ArrayList to add only Employee objects?
Extend ArrayList and customize add() and addAll() method to check the object being added is instanceof Employee
You could use a wrapper class that holds a private ArrayList field, say called employeeList, has a
public void add(Employee employee) {
employeeList.add(employee);
}
as well as any other necessary methods that would allow outside classes to interact with the ArrayList in a controlled fashion.
I find it much better to use composition for this than inheritance. That way if you wanted to change from an ArrayList to something else, say a LinkedList, or even something completely different, you would have an easier time.
You could use Collections.checkedList() - but why would you want to not use generics?
Subclass the ArrayList class and name it something like EmployeeArrayList.
If you're wanting to avoid generics for their own sake, e.g. for compatibility with very old versions of Java, then extending or wrapping ArrayList won't help - you probably want to find or make another array implementation that has the same functionality.
Basically, ArrayList is just a wrapper for a primitive array that copies and pastes its data into a larger array when necessary, so this isn't especially difficult to write from scratch.
What exactly do you want when you "restrict"? There are two possible places where one could place a restriction: at compile-time or runtime.
Generics is a purely compile-time thing. It helps you write correct code but you can still bypass it and put the wrong type in the array and it won't complain at runtime.
On the other hand, something like Collections.checkedList()is a runtime restrictions. It throws an error at runtime when an object of the wrong type comes. But it does not help you at compile-time if you do not have generics.
So the two things are orthogonal, and neither is a replacement for the other. What exactly do you want?

Best way to add functionality to built-in types

I wonder what is the best way in terms of strict OOP to add functionality to built-in types like Strings or integers or more complex objects (in my case the BitSet class).
To be more specific - I got two scenarios:
Adding a md5 hashing method to the String object
Adding conversion methods (like fromByteArray() or toInteger()) to the BitSet class.
Now I wonder what the best practices for implementing this would be.
I could e.g. create a new Class "BitSetEx" extending from BitSet and add my methods. But I don't like the idea since this new class would need describing name and "BitSetWithConversionMethods" sound really silly.
Now I could write a class consisting only of static methods doing the conversions.
Well I got a lot of ideas but I wan't to know what would be the "best" in sense of OOP.
So could someone answer me this question?
There are a few approaches here:
Firstly, you could come up with a better name for the extends BitSet class. No, BitsetWithConversionMethods isn't a good name, but maybe something like ConvertibleBitSet is. Does that convey the intent and usage of the class? If so, it's a good name. Likewise you might have a HashableString (bearing in mind that you can't extend String, as Anthony points out in another answer). This approach of naming child classes with XableY (or XingY, like BufferingPort or SigningEmailSender) can sometimes be a useful one to describe the addition of new behaviour.
That said, I think there's a fair hint in your problem (not being able to find a name) that maybe this isn't a good design decision, and it's trying to do too much. It is generally a good design principle that a class should "do one thing". Obviously, depending on the level of abstraction, that can be stretched to include anything, but it's worth thinking about: do 'manipulating the set/unset state of a number of bits' and 'convert a bit pattern to another format' count as one thing? I'd argue that (especially with the hint that you're having a hard time coming up with a name) they're probably two different responsibilities. If so, having two classes will end up being cleaner, easier to maintain (another rule is that 'a class should have one reason to change'; one class to both manipulate + convert has at least 2 reasons to change), easier to test in isolation, etc.
So without knowing your design, I would suggest maybe two classes; in the BitSet example, have both a BitSet and (say) a BitSetConverter which is responsible for the conversion. If you wanted to get really fancy, perhaps even:
interface BitSetConverter<T> {
T convert(BitSet in);
BitSet parse(T in);
}
then you might have:
BitSetConverter<Integer> intConverter = ...;
Integer i = intConverter.convert(myBitSet);
BitSet new = intConverter.parse(12345);
which really isolates your changes, makes each different converter testable, etc.
(Of course, once you do that, you might like to look at guava and consider using a Function, e.g. a Function<BitSet, Integer> for one case, and Function<Integer, BitSet> for the other. Then you gain a whole ecosystem of Function-supporting code which may be useful)
I would go with the extending class. That is actually what you are doing, extending the current class with some extra methods.
As for the name: you should not name at for the new features, as you might add more later on. It is your extended BitSet class, so BitSetEx allready sounds better then the BitSetWithConversionMethods you propose.
You don't want to write a class with the static methods, this is like procedural programming in an OOP environment, and is considered wrong. You have an object that has certain methods (like the fromByteArray() you want to make) so you want those methods to be in that class. Extending is the way to go.
It depends. As nanne pointed out, subclass is an option. But only sometimes. Strings are declared final, so you cannot create a subclass. You have at least 2 other options:
1) Use 'encapsulation', i.e. create a class MyString which has a String on which it operates (as opposed to extending String, which you cannot do). Basically a wrapper around the String that adds your functionality.
2) Create a utility/helper, i.e. a class with only static methods that operate on Strings. So something like
class OurStringUtil {
....
public static int getMd5Hash(String string) {...}
....
}
Take a look at the Apache StringUtils stuff, it follows this approach; it's wonderful.
"Best way" is kinda subjective. And keep in mind that String is a final class, so you can't extend it.
Two possible approaches are writing wrappers such as StringWrapper(String) with your extra methods, or some kind of StringUtils class full of static methods (since Java 5, static methods can be imported if you wan't to use the util class directly).

Categories

Resources