In Java there is a collection called ArrayList. It allows programmer to add an object of type T and remove them by issuing a simple methods, like
list.remove(object);
list.add(object);
For C++ I've found that standard vectors are using value objects only, so I dont see the way to achieve same functionality.
The case is that I want to hold a reference to an object elsewhere why being able remove or add it using some composition pattern. What I'm asking for is how to achieve something like this in C++:
class Composite {
ArrayList<Composite> children = new ArrayList<>();
public void addChild(Composite child) {
children.add(child);
}
public void removeChild(Composite child) {
children.remove(child)
}
}
class Test{
public static void main() {
Composite a = new Composite();
Composite b = new Composite();
a.addChild(b);
a.removeChild(b);
// from here on a.children is empty.
}
}
I dont even know how to bite this thing in C++. Thanks.
UPDATE: Thanks to the ResidenBiscuit answer and others comments I was able to figure out the basic code for this, which is available at this pastebin url: http://pastebin.com/h17hh3r4
In Java, everything besides POD is a reference. There's no specifying you want a reference, because that's all you get.
Not so much in C++. Everything defaults to value. If you want a std::list of reference types, then you'll need a compiler supporting C++11 std::reference_wrapper. You can then do:
std::list<std::reference_wrapper<Type>> t_list
To add to this list, you would need to use std::ref:
t_list.push_back(std::ref(myObj))
Now everything you add into this list will just be a std::reference_wrapper type. You could also store pointers instead by just doing:
std::list<Type*> tptr_list
Which may be easier, or the only option if you don't have a C++11 compliant compiler.
Related
I have the following simple function that returns the position of a String in a string array (String[]).
private int getIndexOf(String needle, String[] haystack) {
int indexOfNeedle = -1;
for (int index=0;index<haystack.length;index++) {
if (haystack[index].equals(needle)) {
indexOfNeedle = index;
break;
}
}
}
I want to convert this to be a method of the ArrayList class so that I can call it with:
String[] myArray = {"red","green","blue"};
int indexOfGreen = myArray.getIndexOf("green");
(I know there are existing libraries I can include that include indexOf but reinventing this is a lesson for me as well.)
I believe the approach will involve extends ArrayList and that is it probably the class that I need to extend so my function above will need to be modified to fit into that extension class...
Rather than using haystack in the method version I would also expect to be able to search inside this referring to the array object that the method was called from.
I'm also thinking that I may need to replace my String[] arrays with this new extended class of array (or can I use an override to include my new method in the excusing String Array class?).
As I say, this is to help me learn how to do this in general in Java so the exercise itself may seem a bit pointless and the point of the question isn't really to learn how to find the position of an element in an array - that's just by way of an example.
(This answer is based upon the comments, which say that the question is about extension functions)
Java extension functions
Java does not allow extension functions, but there are alternatives you can use instead
Alternatives
Wrapping
You can have a class which contains the original object, and passes through the existing ones you want to use, while implementing the new ones
Extension
You can extend the original object type, but then the instances must be of your new type, rather than the original one
You only need to include the new methods, the rest pass to the super type
Other languages
Some other JVM languages, like Kotlin, do support extension functions, but Java itself does not
Not a good idea.
The best practice is to have a more general type (interface) in the declaration.
void f(List<String> list) { ... }
List<String> list = new ArrayList<>();
This allows other implementations, and being used as parameter is more flexible/powerfull.
Trying to extend these all known classes/interfaces will cause artefacts like rewrapping old classes with new classes and so on.
Instead use static functions in a utility class. Like the Collections and Arrays classes. With a binarySearch and other goodies.
By the way, such functionality as mentioned, probably exists, and one
would like to build upon existing general functionality, instead of reinventing
the wheel.
int index = Arrays.asList(haystack).indexOf(needle);
I want to implement a filter method to a list of elements in java, so I can get rid of some elements in the list according to my filter. And, most important, I want to design the interface as simple as possible.
Here's my implementation:
I created a class named EasierList, and in the class, I added a method whose signature and implementation is like below:
public IEasierList<T> filter(ISelection<T> filter) {
List<T> result = new ArrayList<T>();
for(T item : mInternalList) {
if(filter.accept(item)) {
result.add(item);
}
}
mInternalList = result;
return new EasierList<T>(this);
}
As for the ISelection interface, it is quite a easy one:
public boolean accept(T obj);
So, you can tell, the users who use this class need to write some code like this to use the filter:
aEasierList.filter(new ISelection<T>() {
#Override
public boolean accept(T obj) {
// some test
return false;
}
});
And I'm wondering if there is a better way to do this, I mean to make the interface even easier to use?
Thanks in advance!
Two points:
First, you don't have to reinvent the wheel, you can use Guava which already supports filtering and transforming of collections and iterables. Sure, those methods are static, but you can use them for standard List, Collection or Iterable interfaces.
Second, since Java doesn't yet support lambda expressions (planned for Java 8), the verbose anonymous classes are the only way how to implement a function object (if you don't want to create a full blown named class). However, you can help yourself a little by not implementing the anonymous class in-place, but by storing it in a static field:
private static final Predicate<String> startsWithS = new Predicate<String>() {
#Override public boolean apply(String string) {
return string.startsWith("S");
}
}
And then using it like this:
Collection<String> strings = ...
Collection<String> filtered = Collections2.filter(strings, startsWithS);
Edit:
One more important thing should be mentioned: These filter and transform methods do not create a new collection independent on the original. What they create is a "view", which is technically a proxy object that points to the original collection and lazily applies the given Predicate or Function on its elements during iteration, querying etc.
This is sometimes convenient, but you have to remember, that in order to obtain a new collection that is independent (not deeply, of course) on the original one, you need to pass it to a constructor (or a factory) of a new collection.
List<String> filteredList =
new ArrayList<>(Collections2.filter(strings, startsWithS));
By the way, this might be a good occasion to use static import for the filter method to reduce the verbosity a little.
I think this is the best you can do in native Java without resorting to an alternate JVM language (Groovy, Scala) that supports closures.
Commons Collections implements essentially the same pattern - check out docs for CollectionUtils.filter and Predicate. The only downside is it doesn't support generics.
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html
So if you're going that route, you may as well use something that's already written and tested.
C# also has a good solution to this pattern via LINQ and extension methods, which makes something analogous to the above filter method appear like it belongs to the Collection itself.
Really basic OO comprehension issue I am running into, any help is greatly appreciated.
I'm trying to add instances of "Thing" to an arraylist every-time I press a button, I can't wrap my head around how to create unique instances to add to the list. A different button press should remove the most recent object from the list.
ArrayList myList = new ArrayList<Thing>();
if(input.isKeyPressed(Input.KEY_A)){
Thing myThing = new Thing();
myThing.setNumber(myList.size());
myList.add(myThing);
}
if(input.isKeyPressed(Input.KEY_R)){
if(myList.size()>0){
myList.remove(myList.size()-1);
}
}
If I plan on making lots of "things" and I don't care about what they are called (nor do I want to keep track of unique thing-object names). How can I create a unique 'thing' object on each button press with minimal pain.
UPDATE:
Thanks for the comments, please let me try to articulate my question better...
When I create an ArrayList full of 'Thing', each instance of which is called "myThing", every instance has the same instance variables values.
If I wanted some of the 'Thing''s to have boolean isVisable = true, and other's to have boolean isVisable = false. I get stuck because each element of the list has the same name.
Make sure that Thing implements equals and hashCode correctly and then store the instances in a Set collection (i.e. HashSet). With the implementation of hashCode() and equals() it will be completely up to you which two instances of Thing are the same and hence you will be able to enforce uniqueness any way you need.
Now the trick here is that implementing hashCode() and equals() is not entirely trivial, but you need to know how to do it if you plan to use Java. So read the appropriate chapter of Effective JAva (or better yet read the entire book).
try this:
$ cat Thing.java
import java.util.*;
public class Thing{
UUID id;
Thing () {
id = UUID.randomUUID();
}
public String toString(){
return id.toString();
}
public static void main(String[] argv) {
Thing t = new Thing();
System.out.println(t);
}
}
$ javac Thing.java && java Thing
08bb3702-84d3-4bc3-b8ab-bb52b90b8f78
Is it possible to create new variables in java dynamically.
class A {
methodA(String variableName) {
}
}
So if new method is called twice, 2 new variables should be newly added to this class?
Is it possible?
No. Have you considered storing a Map<String, Object> in the class instead? The keys in the map would be the "variable names" and the values in the map would be the logical variable names.
If you could give more information about what you're trying to achieve (from a high-level perspective) that would help.
No, this is not possible to do in Java.
The fields in a class is determined at compile time and can't be changed during runtime (except though sophisticated techniques such as class reloading though for instance JRebel). I would however not recommend doing this, unless you're writing some IDE for instance.
A class and its members are defined and then compiled to bytecode, so they cannot be readily modified at run-time. That said, there are a number of libraries out there, such as cglib, which provide runtime modification functionality. This page can tell you more: http://java-source.net/open-source/bytecode-libraries
(This is not to say that runtime modification is the right thing to do!)
In a good design, a class must represent something, semantically speaking. You design it to represent an object in your system.
If you want to add more things to a design in run-time, well, something's not quite right -- unless, of course, the design needs adding information in run-time, and there are tons of data structures just ready for the job!
Check out Maps in Java, for example.
Following is the way that i have implemented and helped me to fix my solution easily without much hurdles.
// Creating the array List
List accountList = new ArrayList();
for(int k=0;k < counter;k++){
accountList.add(k, (String)flowCtx.getValueAt("transitId"+m));
}
Iterating the loop and adding the objects into the arraylist with the index.
//Retrieving the object at run time with the help of the index
String a = accountList.get(i));
Using a HashMap could be a solution. For example, if we have the following class:
class Staff {
private HashMap<String, Object> mylist = new HashMap<String, Object>() ;
void setNewVar(String s, Object o) {
mylist .put(s, o);
}
HashMap<String, Object> getVar() {
return mylist;
}
}
I can use it as:
staff.setNewVar("NumVars",11);
staff.setNewVar("NumBatches",300);
...
and then:
staff.getVar()
wherever you need. I use it to convert some variables (the number can change) to JSON, successfully.
I want to create something I can only describe as a "code factory method".
To avoid code repetition, I want to create a method which contains the code to be executed, but with "placeholders" where the types are supposed to go. The method would of course take these types as parameters and place each one in its appropriate spot. For example:
void factory(placeholder1, placeholder2){
ArrayList<placeholder1> List = new ArrayList<placeholder1>;
Placeholder2 variable;
}
factory(String, Integer);
would yield:
ArrayList<String> List = new ArrayList<String>;
Integer variable;
any ideas how I would go about this?
Your help is much appreciated.
EDIT: Thank you for all the feedback. I was going with the generic approach and it was working for awhile until I came across what I believe someone mentioned earlier. I want to use one of the methods within one of the generic objects like:
Integer variable = new Integer();
variable.isInteger();
It doesn't appear that I will be able to do this using generics. Is there possibly a workaround to this?
Rather than simply adopting generics, it looks like you want some sort of macro facility. Java doesn't have that. For example, to expand your example a bit, you couldn't do anything like this:
factory(String, Integer);
List.get(variable);
Here's how it would look:
<placeholder1, placeholder2> void factory(){
ArrayList<placeholder1> List = new ArrayList<placeholder1>;
placeholder2 variable;
}
this.<String, Integer> factory();
But I agree with matt that you should read up on generics. Also, be cautious of type-erasure as this might not do everything you expect.