C# List implementation... in Java - java

I'm learning Java and I'm trying to do something I've always done in C#... in Java.
The goal is to wrap the class "MyItem" into a List of "MyItems". This makes it easier to reason about (MyItems is much easier to read/understand than List<MyItem>... or, say, I need to make it something more complicated like IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>>... then ask for a MyKVPDictionaries instead of List<IEnumerable<KeyValuePair<...>>>>>).
Just looking around... It seems like C# allows you to keep the default implementations of stuff (Look below, .Add just works).
Looking at Java... is there a way to implement a list as done in c#? Or do I have to manually implement the individual parts of the List manually? (.add, .list, .contains, etc).
Below I have a "basic" implementation of a Class... and a List<Class> in C#.
Is it really that much more work to implement class MyItems implements List<MyItem> in Java or am I missing something to simplify the process?
(The Java code is only the MyItems.java class file with Resharper "Auto Implement missing members" stubs via IntelliJ).
C# version .NetFiddle:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var myItems = new MyItems();
myItems.Add(new MyItem("Hello"));
myItems.Add(new MyItem(" "));
myItems.Add(new MyItem("World"));
myItems.Add(new MyItem("!"));
foreach(var item in myItems)
Console.Write(item.Name);
}
}
public class MyItems : List<MyItem>
{
}
public class MyItem
{
public MyItem(string name)
{
Name = name;
}
public string Name { get; private set; }
}
Java Version start/stub:
package items;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class MyItems implements List<MyItem> {
#Override
public int size() {
return 0;
}
#Override
public boolean isEmpty() {
return false;
}
#Override
public boolean contains(Object o) {
return false;
}
#Override
public Iterator<MyItem> iterator() {
return null;
}
#Override
public Object[] toArray() {
return new Object[0];
}
#Override
public <T> T[] toArray(T[] a) {
return null;
}
#Override
public boolean add(MyItem generatePreSignedUrl) {
return false;
}
#Override
public boolean remove(Object o) {
return false;
}
#Override
public boolean containsAll(Collection<?> c) {
return false;
}
#Override
public boolean addAll(Collection<? extends MyItem> c) {
return false;
}
#Override
public boolean addAll(int index, Collection<? extends MyItem> c) {
return false;
}
#Override
public boolean removeAll(Collection<?> c) {
return false;
}
#Override
public boolean retainAll(Collection<?> c) {
return false;
}
#Override
public void clear() {
}
#Override
public MyItem get(int index) {
return null;
}
#Override
public MyItem set(int index, MyItem element) {
return null;
}
#Override
public void add(int index, MyItem element) {
}
#Override
public MyItem remove(int index) {
return null;
}
#Override
public int indexOf(Object o) {
return 0;
}
#Override
public int lastIndexOf(Object o) {
return 0;
}
#Override
public ListIterator<MyItem> listIterator() {
return null;
}
#Override
public ListIterator<MyItem> listIterator(int index) {
return null;
}
#Override
public List<MyItem> subList(int fromIndex, int toIndex) {
return null;
}
}

Java's List type is an interface, the counterpart of C#'s IList. You'll have to write most of the methods from scratch if you want to implement it. The counterpart of C#'s concrete List class would be Java's ArrayList:
public class MyItems extends ArrayList<MyItem> {

Related

void with Generics in Java

I have a function that returns void
public interface IProductService {
void delete(String id);
}
Generic method
public interface IRequestHandler<C , R> {
R handler(C c);
Class<C> commandType();
}
Implementation of generic interface
#Singleton
public record DeleteProductCommandHandler(IProductService iProductService)
implements IRequestHandler<DeleteProductCommand, Void> {
#Override
public Void handler(DeleteProductCommand deleteProductCommand) {
return iProductService.delete(deleteProductCommand.id);
}
#Override
public Class<DeleteProductCommand> commandType() {
return DeleteProductCommand.class;
}
}
How can I use void in IRequestHandler<DeleteProductCommand, Void> so that I can map void from iProductService.delete(deleteProductCommand.id);
Option 1:
Just return null:
#Override
public Void handler(DeleteProductCommand deleteProductCommand) {
iProductService.delete(deleteProductCommand.id);
return null;
}
Option 2:
Update the IProductService::delete method to return something meaningful, e.g. a boolean value like Collection::remove does:
public interface IProductService {
boolean delete(String id);
}
#Singleton
public record DeleteProductCommandHandler(IProductService iProductService)
implements IRequestHandler<DeleteProductCommand, Boolean> {
#Override
public Boolean handler(DeleteProductCommand deleteProductCommand) {
return iProductService.delete(deleteProductCommand.id);
}
#Override
public Class<DeleteProductCommand> commandType() {
return DeleteProductCommand.class;
}
}

How to implement and fire an event when a change occurs in a property of `T` in `List<T>` within the owning class in Java

Any clue if it is possible to convert code below to Java (Android) from C#?
It is based on my prev.question
How to implement and fire an event when a change occurs in a property of `T` in `List<T>` within the owning class
public class ItemPropertyChangedNotifyingList<T> : IList<T>, INotifyPropertyChanged where T : INotifyPropertyChanged
{
private List<T> _listImplementation = new List<T>();
public void Add(T item)
{
item.PropertyChanged += ItemOnPropertyChanged;
_listImplementation.Add(item);
}
private void ItemOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
PropertyChanged?.Invoke(sender, e);
}
public IEnumerator<T> GetEnumerator()
{
return _listImplementation.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_listImplementation).GetEnumerator();
}
public void Clear()
{
_listImplementation.ForEach(x => x.PropertyChanged -= ItemOnPropertyChanged);
_listImplementation.Clear();
}
public bool Contains(T item)
{
return _listImplementation.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_listImplementation.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
item.PropertyChanged -= ItemOnPropertyChanged;
return _listImplementation.Remove(item);
}
public int Count => _listImplementation.Count;
public bool IsReadOnly => false;
public int IndexOf(T item)
{
return _listImplementation.IndexOf(item);
}
public void Insert(int index, T item)
{
item.PropertyChanged += ItemOnPropertyChanged;
_listImplementation.Insert(index, item);
}
public void RemoveAt(int index)
{
_listImplementation.RemoveAt(index);
}
public T this[int index]
{
get => _listImplementation[index];
set => _listImplementation[index] = value;
}
public event PropertyChangedEventHandler PropertyChanged;
}
Have we use PropertyChangeListener for this task? Like it is shown here.
public FocusManagerListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if ("focusOwner".equals(propertyName) {
...
} else if ("focusedWindow".equals(propertyName) {
...
}
}
...
}
I just ported ItemPropertyChangedNotifyingList to ItemChangeList.
In code, I changed this part.
Used 'ArrayList' to hold elements instead of 'List` in C#
In copyTo, I used Java 8 Stream. Since you tag 'android', I used Lightweight-Stream-API to achieve same feature of copyTo.
Java doesn't support get, set syntax, i divide to two methods.
import com.annimon.stream.Stream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ItemChangedList<T> {
private List<T> _listImplementation = new ArrayList<>();
private List<OnPropertyChangedObserver<T>> _changedObserverList = new ArrayList<>();
public static final String ITEM_ADDED = "bbed36af-0b7b-4e53-abc9-02d6a14d7f34";
public static final String ITEM_REMOVED = "7390116e-586d-4e62-9343-5b82b0a8c6c5";
public void add(T item) {
sendPropertyChanged(item, ITEM_ADDED);
_listImplementation.add(item);
}
public Iterator<T> iterator() {
return _listImplementation.iterator();
}
public void clear() {
for (T item : _listImplementation) {
sendPropertyChanged(item, ITEM_REMOVED);
}
_listImplementation.clear();
}
public boolean contains(T item) {
return _listImplementation.contains(item);
}
public void copyTo(T[] array, int arrayIndex) {
// Using https://github.com/aNNiMON/Lightweight-Stream-API
_listImplementation.addAll(Stream.of(array).skip(arrayIndex).toList());
// Traditional Java way
// _listImplementation.addAll(Arrays.stream(array).skip(arrayIndex).collect(Collectors.toList()));
}
public boolean remove(T item) {
sendPropertyChanged(item, ITEM_REMOVED);
return _listImplementation.remove(item);
}
public int count() {
return _listImplementation.size();
}
public boolean isReadOnly() {
return false;
}
public int indexOf(T item) {
return _listImplementation.indexOf(item);
}
public void insert(int index, T item) {
sendPropertyChanged(item, ITEM_ADDED);
_listImplementation.add(index, item);
}
public void removeAt(int index) {
_listImplementation.remove(index);
}
public T get(int index) {
return _listImplementation.get(index);
}
public void set(int index, T item) {
_listImplementation.set(index, item);
}
public void addObserver(OnPropertyChangedObserver<T> observer) {
_changedObserverList.add(observer);
}
public void removeObserver(OnPropertyChangedObserver<T> observer) {
_changedObserverList.remove(observer);
}
public void clearObserver() {
_changedObserverList.clear();
}
private void sendPropertyChanged(T item, String args) {
for (OnPropertyChangedObserver<T> observer : _changedObserverList) {
observer.onChanged(item, args);
}
}
public interface OnPropertyChangedObserver<T> {
void onChanged(T item, String args);
}
}
Other way is extends ArrayList instead _listImplementation. it can be provide more functionally. Personally, I prefer this way. Gist
Edit-1) Oh, i forget add args in OnPropertyChangeObserver.
Edit-2) Let Kotlin optimize this! Gist

Use Vaadin TreeTable like a normal Tree

Since Vaadin Tree does not support lazy loading I would like to use the TreeTable.
The TreeTable should look like a normal Tree, without headers and zebra row style.
This is what I got so far:
TreeTable mainTree = new TreeTable();
mainTree.setSizeFull();
mainTree.setColumnHeaderMode(ColumnHeaderMode.HIDDEN);
mainTree.setColumnCollapsingAllowed(false);
What else should I set and how do I get rid of the zebra pattern?
Consider implenting a lazy load mechanism yourself, wherein you load the root of three. Then you add an ExpandListener which, upon called, loads the children objects and adds them to the node.
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
final Tree t = new Tree();
t.addItem(new TreeNode(0));
t.addExpandListener(new ExpandListener() {
#Override
public void nodeExpand(ExpandEvent event) {
TreeNode node = (TreeNode) event.getItemId();
for (TreeNode child : node.getMyChildren()){
t.addItem(child);
t.setParent(child, node);
}
}
});
layout.addComponent(t);
}
}
Even though in Vaadin documentation it says lazy loading for Tree is not supported, I managed to implement the following lazy loading Hierarchical interface.
It's very important to store all elements in a local structure (in my case in the HashMap hierarchy), do not read elements multiple times this does not work. I think because Vaadin does not use equals() and hashCode().
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.softmodeler.common.CommonPlugin;
import com.softmodeler.model.OutputNode;
import com.softmodeler.service.IViewService;
import com.vaadin.data.Container.Hierarchical;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.BeanItem;
/**
* #author Flavio Donzé
* #version 1.0
*/
public class OutputNodeHierachical implements Hierarchical {
private static final long serialVersionUID = 8289589835030184018L;
/** the view service */
private IViewService service = CommonPlugin.getService(IViewService.class);
/** collection of all root nodes */
private List<OutputNode> rootNodes = null;
/** parent=>children mapping */
private Map<OutputNode, List<OutputNode>> hierarchy = new HashMap<>();
/**
* constructor
*
* #param rootNodes collection of all root nodes
*/
public OutputNodeHierachical(List<OutputNode> rootNodes) {
this.rootNodes = Collections.unmodifiableList(rootNodes);
addToHierarchy(rootNodes);
}
#Override
public Collection<?> getChildren(Object itemId) {
try {
List<OutputNode> children = hierarchy.get(itemId);
if (children == null) {
OutputNode node = (OutputNode) itemId;
children = service.getChildren(node.getNodeId(), false);
hierarchy.put(node, children);
// add children to hierarchy, their children will be added on click
addToHierarchy(children);
}
return children;
} catch (Exception e) {
VaadinUtil.handleException(e);
}
return null;
}
/**
* add each element to the hierarchy without their children hierarchy(child=>null)
*
* #param children elements to add
*/
private void addToHierarchy(List<OutputNode> children) {
for (OutputNode child : children) {
hierarchy.put(child, null);
}
}
#Override
public boolean areChildrenAllowed(Object itemId) {
return !((OutputNode) itemId).getChilds().isEmpty();
}
#Override
public boolean hasChildren(Object itemId) {
return !((OutputNode) itemId).getChilds().isEmpty();
}
#Override
public Object getParent(Object itemId) {
String parentId = ((OutputNode) itemId).getParentId();
for (OutputNode node : hierarchy.keySet()) {
if (node.getNodeId().equals(parentId)) {
return node;
}
}
return null;
}
#Override
public Collection<?> rootItemIds() {
return rootNodes;
}
#Override
public boolean isRoot(Object itemId) {
return rootNodes.contains(itemId);
}
#Override
public Item getItem(Object itemId) {
return new BeanItem<OutputNode>((OutputNode) itemId);
}
#Override
public boolean containsId(Object itemId) {
return hierarchy.containsKey(itemId);
}
#Override
public Collection<?> getItemIds() {
return hierarchy.keySet();
}
#Override
public int size() {
return hierarchy.size();
}
#Override
public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
#Override
public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
#Override
public Item addItem(Object itemId) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
#Override
public Object addItem() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
#Override
public boolean removeItem(Object itemId) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
#Override
public boolean removeAllItems() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
#Override
public Class<?> getType(Object propertyId) {
throw new UnsupportedOperationException();
}
#Override
public Collection<?> getContainerPropertyIds() {
throw new UnsupportedOperationException();
}
#Override
public Property<?> getContainerProperty(Object itemId, Object propertyId) {
throw new UnsupportedOperationException();
}
#Override
public boolean addContainerProperty(Object propertyId, Class<?> type, Object defaultValue) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
#Override
public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
}
Adding the container to the Tree like this:
OutputNodeHierachical dataSource = new OutputNodeHierachical(rootNodes);
Tree mainTree = new Tree();
mainTree.setSizeFull();
mainTree.setContainerDataSource(dataSource);
mainTree.addItemClickListener(new ItemClickListener() {
private static final long serialVersionUID = -413371711541672605L;
#Override
public void itemClick(ItemClickEvent event) {
OutputNode node = (OutputNode) event.getItemId();
openObject(node.getObjectId());
}
});

JavaFX Property for a BitSet

I need a JavaFX Property for a BitSet in order to create a TableColumn with a toggle button for each bit in the BitSet. I have implemented Property<BitSet> but even with the oracle documentation the meaning and usage of some of the interface methods still eludes me, as for me this all looks like superfluous boilerplate. Please tell me if I am on the right track with the implementation and what I can improve. I didn't implement bindings yet because I don't expect to need them for my use case.
import java.util.*;
import javafx.beans.InvalidationListener;
import javafx.beans.property.Property;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
public class BitSetProperty implements Property<BitSet>
{
private BitSet value;
private final Set<ChangeListener<? super BitSet>> changeListeners = new HashSet<>();
private final Set<InvalidationListener> invalidationListeners = new HashSet<>();
#Override public Object getBean() {return value;}
#Override public String getName() {return "what shall I return here?";}
#Override public void addListener(ChangeListener<? super BitSet> listener) {changeListeners.add(listener);}
#Override public void removeListener(ChangeListener<? super BitSet> listener) {changeListeners.remove(listener);}
#Override public BitSet getValue()
{
return (BitSet)value.clone();
}
#Override public void addListener(InvalidationListener listener) {invalidationListeners.add(listener);}
#Override public void removeListener(InvalidationListener listener) {invalidationListeners.remove(listener);}
#Override public void setValue(BitSet value)
{
if(!value.equals(this.value))
{
changeListeners.stream().forEach(cl->cl.changed(this, this.value, (BitSet)value.clone()));
invalidationListeners.stream().forEach(il->il.invalidated(this));
}
this.value=value;
}
#Override public void bind(ObservableValue<? extends BitSet> observable)
{
throw new UnsupportedOperationException();
}
#Override public void unbind()
{
throw new UnsupportedOperationException();
}
#Override public boolean isBound()
{
// TODO Auto-generated method stub
return false;
}
#Override public void bindBidirectional(Property<BitSet> other)
{
throw new UnsupportedOperationException();
}
#Override public void unbindBidirectional(Property<BitSet> other)
{
throw new UnsupportedOperationException();
}
}
Answering my own question as it turns out I misunderstood how properties work.
I thought they trigger change events when the internal state changes but I know now that they treat the content as a black box (I guess assuming the content is immutable) and just trigger when the content is replaced, which is a much easier problem. My question can then be solved using:
ObjectProperty<BitSet> property = new SimpleObjectProperty<>();

Equivalent of C# ObservableCollection in Java

I was wondering if there is a data structure that acts like an OberservableCollection almost like in C# that is able to take a certain type.
ex:
In C# i am able to say..
ObservableCollection<Beer> Beer = new ObservableCollection<Beer>();
Beer.add("Bud"); <br>
Beer.add("Coors");
Assuming that the class Beer is made and we can change the alcohol content so that
Beer[1].content = 5;
I was wondering if anyone knows if there is such a data structure/s that work as well with Java.
I am a C# programmer, not much of a Java programmer so just wondering. Also, it has to be able to take in a custom type, not generic.
org.apache.commons.events.observable
Class ObservableCollection
Observable data structures (ObservableList, ObservableMap, etc) are included in Oracle Java 7u6+ as part of the JavaFX project. A corresponding library for OpenJDK is provided by the OpenJFX project.
Here is a tutorial on using JavaFX collections.
And some sample code for using a JavaFX observable list from the linked tutorial:
import java.util.List;
import java.util.ArrayList;
import javafx.collections.*;
public class CollectionsDemo {
public static void main(String[] args) {
// Use Java Collections to create the List.
List<String> list = new ArrayList<String>();
// Now add observability by wrapping it with ObservableList.
ObservableList<String> observableList = FXCollections.observableList(list);
observableList.addListener(new ListChangeListener() {
#Override public void onChanged(ListChangeListener.Change change) {
System.out.println("Detected a change! ");
}
});
// Changes to the observableList WILL be reported.
// This line will print out "Detected a change!"
observableList.add("item one");
// Changes to the underlying list will NOT be reported
// Nothing will be printed as a result of the next line.
list.add("item two");
System.out.println("Size: "+observableList.size());
}
}
If you want to Observe your lists, i.e. be notified when list changes, you can use Glazed Lists.
If you just want to modify objects stored in your lists, you can get your objects by using List.get(int index), or by iterating the list.
If you want to automatically create Beer objects when storing Strings into the list, you'll probably need to write your own simple list wrapper.
JavaFX now has ObservableList that match your needs, in the case that you don't want to depend on JavaFX - here is a class that I wrote a while ago that can be used instead.
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
*
* #author bennyl
*/
public class ObservableList<T> implements List<T> {
private List<T> wrapped;
private LinkedList<Listener<T>> listeners = new LinkedList<>();
public ObservableList(List wrapped) {
this.wrapped = wrapped;
}
public void addListener(Listener l) {
listeners.add(l);
}
public void removeListener(Listener l) {
listeners.remove(l);
}
#Override
public int size() {
return wrapped.size();
}
#Override
public boolean isEmpty() {
return wrapped.isEmpty();
}
#Override
public boolean contains(Object o) {
return wrapped.contains(o);
}
#Override
public Iterator<T> iterator() {
final Iterator<T> iterator = wrapped.iterator();
return new Iterator<T>() {
T current = null;
#Override
public boolean hasNext() {
return iterator.hasNext();
}
#Override
public T next() {
return current = iterator.next();
}
#Override
public void remove() {
iterator.remove();
fireRemoved(current);
}
};
}
private void fireRemoved(T... items) {
fireRemoved(Arrays.asList(items));
}
#Override
public Object[] toArray() {
return wrapped.toArray();
}
#Override
public <T> T[] toArray(T[] a) {
return wrapped.toArray(a);
}
#Override
public boolean add(T e) {
if (wrapped.add(e)) {
fireAdded(e);
return true;
} else {
return false;
}
}
#Override
public boolean remove(Object o) {
if (wrapped.remove(o)) {
fireRemoved((T) o);
return true;
}
return false;
}
#Override
public boolean containsAll(Collection<?> c) {
return wrapped.containsAll(c);
}
#Override
public boolean addAll(Collection<? extends T> c) {
if (wrapped.addAll(c)) {
fireAdded(c);
return true;
}
return false;
}
#Override
public boolean addAll(int index, Collection<? extends T> c) {
if (wrapped.addAll(index, c)) {
fireAdded(c);
}
return false;
}
#Override
public boolean removeAll(Collection<?> c) {
if (wrapped.removeAll(c)) {
fireRemoved((Collection<? extends T>) c);
return true;
}
return false;
}
#Override
public boolean retainAll(Collection<?> c) {
if (wrapped.retainAll(c)) {
fireStracturalChange();
}
return false;
}
#Override
public void clear() {
wrapped.clear();
fireStracturalChange();
}
#Override
public boolean equals(Object o) {
return wrapped.equals(o);
}
#Override
public int hashCode() {
return wrapped.hashCode();
}
#Override
public T get(int index) {
return wrapped.get(index);
}
#Override
public T set(int index, T element) {
T old = wrapped.set(index, element);
fireRemoved(old);
fireAdded(element);
return old;
}
#Override
public void add(int index, T element) {
wrapped.add(index, element);
fireAdded(element);
}
#Override
public T remove(int index) {
T old = wrapped.remove(index);
fireRemoved(old);
return old;
}
#Override
public int indexOf(Object o) {
return wrapped.indexOf(o);
}
#Override
public int lastIndexOf(Object o) {
return wrapped.lastIndexOf(o);
}
#Override
public ListIterator<T> listIterator() {
return wrapped.listIterator();
}
#Override
public ListIterator<T> listIterator(int index) {
return wrapped.listIterator(index);
}
#Override
public List<T> subList(int fromIndex, int toIndex) {
return wrapped.subList(fromIndex, toIndex);
}
private void fireRemoved(Collection<? extends T> asList) {
for (Listener<T> l : listeners) {
l.onItemsRemoved(this, asList);
}
}
private void fireAdded(T... e) {
fireAdded(Arrays.asList(e));
}
private void fireAdded(Collection<? extends T> asList) {
for (Listener<T> l : listeners) {
l.onItemsAdded(this, asList);
}
}
private void fireStracturalChange() {
for (Listener<T> l : listeners) {
l.onStracturalChange(this);
}
}
public static interface Listener<T> {
void onItemsAdded(ObservableList<T> source, Collection<? extends T> items);
void onItemsRemoved(ObservableList<T> source, Collection<? extends T> items);
void onStracturalChange(ObservableList<T> source);
}
}
There isn't at least in Java Collections api
http://download-llnw.oracle.com/javase/1.5.0/docs/guide/collections/designfaq.html#27
You can create an wrapper or proxy
You can consider using the java.util.Observable class, here is an example :
public class Try extends Observable{
private static List<String> list = new ArrayList<String>();
private static Try observableObj = new Try();
public static List<String> getList(){
observableObj.setChanged();
observableObj.notifyObservers();
return list;
}
public static void main(String[] args) throws RemoteException {
Try2 observer1 = new Try2();
Try2 observer2 = new Try2();
observableObj.addObserver(observer1);
observableObj.addObserver(observer2);
System.out.println(getList().isEmpty());
}
}
class Try2 implements Observer{
#Override
public void update(Observable arg0, Object arg1) {
System.out.println(this.toString()+" has been notified");
}
}
In this way every time the ArrayList gets accessed the two observers get notified.
Sure, you can do this. If you had a class called Soda, you could do:
List<Soda> sodas = new ArrayList<Soda>();
sodas.add(new Soda("Coke"));
sodas.add(new Soda("Sprite"));
Then you could do
sodas.get(1).setSugar(255);

Categories