I'm designing a class which has a purpose of being an immutable container for some objects. It happens very often that the Container object is holding just a single object and since it's immutable, I tend to implement it as follows:
public abstract class Container{
public abstract Iterable<Object> getObjectGroup();
private Container(){ }
public static Container createSingle(final Object o) {
return new Container() {
#Override
public Iterable<Object> getObjectGroup() {
return new Iterable<Object>() {
#Override
public Iterator<Object> iterator() {
return new Iterator<Object>() {
private boolean next = true;
#Override
public boolean hasNext() {
return next;
}
#Override
public Object next() {
next = false;
return o;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Unable to remove from an immutable container");
}
};
}
};
}
};
}
public static Container createMultiple(final Collection<Object> o) {
return new Container() {
#Override
public Iterable<Object> getObjectGroup() {
return Collections.unmodifiableCollection(o);
}
};
}
}
QUESTION: Is it actually justified to make such a distinction between containers for single and multiple objects. I primiraly do this in order to not waste the memory for creating a specific collection object like ArrayList<T> or TreeSet<T> which is definitely redundant in case of a single-object Container.
There is no absolute answer to this question: Whether the distinction between a uni-object container and a multi-object container is justified depends totally on the context of your problem.
I would say that unless you already know that you are running into memory issues and that the memory issue is caused by these collections, it is a premature optimization that just adds complexity. And even if you are running into performance issues, there is likely something better to optimize than this code.
So the answer should probably be the same as it is to every other question of form "Should I increase complexity to optimize time/memory usage": Not unless it is a problem.
Related
I know the Java compiler generates different classes for lambda functions depending on the context and closure they have. When I receive the lambda as a parameter (using the Consumer<> class), may I know the lifetime of the parameter?
For example, I have the following Observable class, that keeps a weak reference to its observes.
class Observable {
private final List<WeakReference<Consumer<Object>>> observables = new ArrayList<>();
private Object obj;
public Observable(Object obj){
this.obj = obj;
}
public void observe(Consumer<Object> cons){
this.observables.add(new WeakReference<>(cons));
}
public void set(Object obj){
this.obj = obj;
// notify observes
for(WeakReference<Consumer<Object>> cons : this.observables){
if(cons.get() != null)
cons.get().accept(this.obj);
// clearing the non-existing observes from the list is ommited for simplicity
}
}
}
Now I use it as follows.
public class Main {
public static void main(String[] args) {
Object c = new Object();
Observable obs = new Observable(c);
new ContainingClass(obs);
obs.set(c);
System.gc();
obs.set(c);
}
}
The code just creates the object and its observer and creates ContainingClass (definition follows) that observes. Then the object is set once, garbage collector explicitly called (so the created ContainingClass is deleted) and set the object a second time.
Now, as long as the lambda is instance-specific (reference either this or its instances method) it's called only once (because it is destroyed by the GC).
public class ContainingClass {
public ContainingClass(Observable obs){
obs.observe(this::myMethod);
}
private void myMethod(Object obj) {
System.out.println("Hello here");
}
}
public class ContainingClass {
private Object obj;
public ContainingClass(Observable obs){
obs.observe(obj -> {
this.obj = obj;
System.out.println("Hello here");
});
}
}
But as the lambda becomes static, it is called twice, even after GC.
public class ContainingClass {
public ContainingClass(Observable obs){
obs.observe((obj) -> System.out.println("Hello here"));
}
}
The reference to this lambda is never destroyed and therefore add as an observer every time ContainingClass instance is created. As a result, it will be stuck in observers until the program ends.
Is there a way to detect this and at least show a warning, that the lambda will be never removed?
One thing I figured out is that lambda with instance lifetime has arg$1 property, so I can ask about the number of properties.
public void observe(Consumer<Object> cons){
if(cons.getClass().getDeclaredFields().length == 0)
System.out.println("It is static lifetime lambda");
this.observables.add(new WeakReference<>(cons));
}
Is it a universal approach? May there be a situation when this doesn't work?
I think a good solution would be the one hinted by #Olivier: you can return an object with a remove method that removes your Consumer from your list when called, like the following example:
#FunctionalInterface
public interface Registration {
void remove();
}
class Observable {
private final List<Consumer<Object>> observables = new ArrayList<>();
private Object obj;
public Observable(Object obj) {
this.obj = obj;
}
public Registration observe(Consumer<Object> cons) {
this.observables.add(cons);
return () -> this.observables.remove(cons);
}
public void set(Object obj) {
[...]
}
}
The alternative would be to check if the class the lambda belongs to is static or not, as suggested by #kutschkem, but I don't like resorting to introspection if there is a good alternative.
As already stated by #shalk, relying on WeakReference to handle GC can lead to unwanted behaviours, because there is no way to ensure that your Consumer isn't referenced (maybe by mistake) somewhere else.
Your question is similar to this question, so the answers there apply here too.
A static nested class has a flag that can be checked:
Modifier.isStatic(clazz.getModifiers()) // returns true if a class is static, false if not
I was working on my Minecraft mod recently and while working on the return statement of a function, I found out it needs an instance of INBT for the return type. I have a custom object that I need to convert to an NBT of type INBT?
Here is the function:
public INBT writeNBT(Capability<IAllergies> capability, IAllergies instance, Direction side) {
return null;
}
I have looked at the type hierarchy of INBT and found nothing that might be of any use.
Thanks in advance,
Kid Koder
No, you shouldn't be creating your own class.
It depends on what you want, but there are many classes, from CompountNBT (which is a bit like a Map), ListNBT (a list of INBT), to BooleanNBT, StringNBT, IntegerNBT etc.
Look at the type hierachy of INBT and pick the one you need.
I found out how to do it.
What I did was created an ObjectNBT class the implemented INBT, and wrote a few methods to get/set the Object here is what my final class looked like:
public class ObjectNBT implements INBT {
public Object object;
public ObjectNBT(Object object) {
this.object = object;
}
#Override
public void write(DataOutput output) throws IOException {
}
#Override
public byte getId() {
return 0;
}
#Override
public INBTType<?> func_225647_b_() {
return null;
}
#Override
public INBT copy() {
return null;
}
#Override
public ITextComponent toFormattedComponent(String indentation, int indentDepth) {
return new StringTextComponent(indentation + indentDepth);
}
}
Feel free to copy and paste.
I have an object that has a variable that I want to be able to hold either a queue or a stack. Anything that has an add and a remove with the appropriate logics. I think this can be done with an interface but the two in java.util doesn't have the same interface or even the same name for the two operations.
My plan right now is to create a wrapper to make them fit what I want, but this seems inelegant. Is there a better way?
I want something like:
Something<E> steps;
So that I can call step.pop() and step.push() or whatever method names without having to know if steps implements queue logic or stack logic.
You might want either ArrayDeque or LinkedList depending on your needs.
Both implement Deque (double ended queue).
From the Javadoc on ArrayDeque: "This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue."
Elements can be added or removed from either end of a Deque.
A Deque can be used as a queue by calling addLast and removeFirst, and can also be used by a stack by using addLast and removeLast.
If you really want it to behave like either one, you can keep a boolean flag and write helper methods, or you can write a class:
public class QueueOrStack<E> implements Iterable<E> {
private Deque<E> container = new ArrayDeque<E>();
private boolean isQueue;
public QueueOrStack(boolean isQueue) {
this.isQueue = isQueue;
}
public E pop() {
return isQueue ? container.removeFirst() : container.removeLast();
}
public void push(E element) {
container.addLast(element);
}
public void pushAll(E... element) {
for (E e : element)
container.addLast(e);
}
public boolean isQueue() {
return isQueue;
}
public void setQueue(boolean isQueue) {
this.isQueue = isQueue;
}
public boolean toggleQueue() {
return isQueue = !isQueue;
}
#Override
public Iterator<E> iterator() {
return container.iterator();
}
}
Here's the test:
QueueOrStack<String> strings = new QueueOrStack<>(true);
strings.pushAll("hello", ", " , "world\n");
for(String s : strings)
System.out.print(s); //"hello, world"
System.out.println(strings.pop()); //"hello"
strings.toggleQueue();
System.out.println(strings.pop()); //"world"
I'm trying to create a simple way to fire CRUD-type events for different domain classes. I've created the following event class:
public class EntityModifiedEvent<E> extends Event<EntityModifiedEventHandler<E>> {
private E element;
private ModType modType;
private Class<E> clazz;
private static Map<String,GwtEvent.Type<EntityModifiedEventHandler<?>>> types = new HashMap<String, GwtEvent.Type<EntityModifiedEventHandler<?>>>();
public EntityModifiedEvent(ModType modType, E element, Class<E> clazz) {
this.element = element;
this.modType = modType;
this.clazz = clazz;
}
public Type<EntityModifiedEventHandler<?>> getType() {
return getType(clazz);
}
#SuppressWarnings({"rawtypes", "unchecked"})
public static GwtEvent.Type<EntityModifiedEventHandler<?>> getType(Class clazz) {
GwtEvent.Type type = types.get(clazz.toString());
if (type == null) {
type = new GwtEvent.Type<EntityModifiedEventHandler<?>>();
types.put(clazz.toString(), type);
}
return type;
}
public E getElement(){
return element;
}
public ModType getModType() {
return modType;
}
#SuppressWarnings({"unchecked", "rawtypes"})
#Override
public Type<EntityModifiedEventHandler<E>> getAssociatedType() {
return (Type) getType();
}
#Override
protected void dispatch(EntityModifiedEventHandler<E> handler) {
handler.onEntityModified(this);
};
public interface EntityModifiedEventHandler<E> extends EventHandler {
void onEntityModified(EntityModifiedEvent<E> entityModifiedEvent);
}
So, any class can register itself as a listener as follow:
getEventBus().addHandler(EntityModifiedEvent.getType(MyDomainClass.class), this);
And the events will be fired like:
getEventBus().fireEventFromSource(new EntityModifiedEvent<MyDomainClass>(ModType.CREATE, instanceModified, MyDomainClass.class), this);
ModType is just a simple Enum with the different types of modifications.
I have some concerns about having a map with all class.toString->eventTypes in this class itself. Do you think this will bring performance issues?
Also, this approach relies on the EventBus using Type object's hashcode to identify the handlers registered for that type (see getType(Class clazz) function). Do you think it's wrong to rely on it?
Any other suggestion about how to do this? Any comment will be much appreciated!
You have to ask yourself what do you gain from such an approach?
Performance - no. I don't have solid numbers on this (I'd have to be able to profile your application), but it's seems that this offers no measurable performance gains, if any. The number of fired events will be the same, but the number of receivers will be greater than with a more fine-grained approach. Plus, there's the type checking.
The ability to perform some common code when any entity modified event is fired, regardless of its type. This is true, but read on on how to achieve it with specific events.
Using specific events for the exact operation that was performed seems like a better choice:
It makes it clear who listens to what event.
The events can have extra metadata specific to the event (how many records where deleted, do you need to flush the cache, etc.)
I'd recommend looking at gwteventbinder to trim some of the boilerplate and improve your code. It also allows for handling several events in one method:
class SuperEvent extends GenericEvent { }
class EventOne extends SuperEvent { }
class EventTwo extends SuperEvent { }
class FormPresenter {
interface MyEventBinder extends EventBinder<FormPresenter> {}
private final MyEventBinder eventBinder = GWT.create(MyEventBinder.class);
FormPresenter(EventBus eventBus) {
eventBinder.bindEventHandlers(this, eventBus);
}
#EventHandler
void onEventOne(EventOne event) {
// handler for EventOne
}
#EventHandler(handles = {EventOne.class, EventTwo.class})
void onEventOneAndTwo(SuperEvent event) {
// handler for EventOne and EventTwo
}
#EventHandler(handles = {EventOne.class, EventTwo.class})
void onEventOneAndTwo2() {
// handler for EventOne and EventTwo without parameter
}
}
I would like to write the following code:
boolean found = false;
search(new SearchCallback() {
#Override void onFound(Object o) { found = true; }
});
Obviously this is not allowed, since found needs to be final. I can't make found a member field for thread-safety reasons. What is the best alternative? One workaround is to define
final class MutableReference<T> {
private T value;
MutableReference(T value) { this.value = value; }
T get() { return value; }
void set(T value) { this.value = value; }
}
but this ends up taking a lot of space when formatted properly, and I'd rather not reinvent the wheel if at all possible. I could use a List<Boolean> with a single element (either mutating that element, or else emptying the list) or even a Boolean[1]. But everything seems to smell funny, since none of the options are being used as they were intended.
What is a reasonable way to do this?
I tend to do the boolean[1] method you mentioned:
final boolean[] found = {false};
search(new SearchCallback() {
#Override void onFound(Object o) { found[0] = true; }
});
It's a bit hackish, but it tends to be the closest thing to what you actually want
You could go all functional:
Boolean found = search(new SearchCallback<Boolean>() {
#Override Boolean onFound(Object o) { return true; }
});
Usually if you want to mutate an enclosing variable, you can express a solution more clearly by not doing so.
All solutions are indeed hackish, but the array is the "standard" textbook way of handling it, as even pre-generics it was typesafe.
Another option in this situation is to make a private class like so:
private class Searcher implements SearchCallback {
private boolean found;
#Override public void onFound(Object o) { found = true; }
public boolean search() {
OuterClass.this.search(this);
return found;
}
}
And then use it like so:
boolean found = new Searcher().search();
Edit: If I understand Tom's comment correctly, he is suggesting this as an alternative
public void foo() { //This is the method that enclosed the code in your question
new SearchCallBack() {
private boolean found;
#Override public void onFound(Object o) { found = true; }
{
//The code that was before this in your method
search(this);
//The code that was after this in your method
}
};
}
I think that is more hackish and I would really find such code unusual, but it is definitely worth knowing that it is an option.
If you really cant use a field, Michael answers seems right.
Anyway. I dont know what signatures you can touch, but it seems to me that that callback is intented to do something (when the search succeeds) with/to the found object. You, instead, are intending to notify the caller of the search method that it found something. It would seems much more natural if your seach() method were made to return a boolean (the method will surely call s.onFound() somewhere if the search succeeds, then set an internal found flag there and return it).