I want to use ArrayList for example but besides only keeping an entry I want to store additional information: "write-in" time, some flag maybe. I could extend the class I am going to store but I want it to be the list feater. I thought maybe to do something like
public class PropertirizedArrayList<E> implements List<E> {
private static class TupleContainer<E>{
public E mainValue;
public Long hidingTime;
public Boolean flag;
}
private ArrayList<TupleContainer<E>> list = new ArrayList<>();
private ArrayList<TupleContainer<E>> delegate(){
return list;
}
//etc...
}
but I think it would be a great problem to reimplement all the List interface methods.
You can simply use List<TupleContainer<SomeType>>. I don't see a need to wrap the List with PropertirizedArrayList.
And if you do have some good reason to use a wrapper class (such a reason would be additional features that your wrapped list implements), you don't have to re-implement the existing List methods.
You have a List member contained within your class, so you can delegate each method of your class to the list.
For example :
public TupleContainer<E> get (int index)
{
return list.get (index);
}
Or if you don't want to expose TupleContainer :
public E get (int index)
{
return list.get (index).mainValue;
}
try this ...
private class TupleContainer<E>{
public E mainValue;
public Long hidingTime;
public Boolean flag;
}
List<TupleContainer<YourType>> list=new ArrayList<TupleContainer<YourType>>();
TupleContainer<YourType> tc=new TupleContainer<YourType>();
tc.mainValue=value;
tc.hidingTime=value;
tc.flag=value;
list.add(tc);
Related
I am trying to create class that extends the java.util.ArrayList by overriding
the add method in the following way: it does nothing if the object to be added already exists
in the collection; otherwise it calls the add method in the super class to add the object into
the collection.
My code look like that so far but it gives a NullPointerException:
import java.util.ArrayList;
public class myArrayList<E> extends ArrayList<E> {
public ArrayList<E> mylist;
#Override
public boolean add(E e) {
if (!mylist.contains(e)) {
super.add(e);
return true;
} else {
return false;
}
}
}
public static void main(String[] args) {
myArrayList<Integer> listing = new myArrayList<Integer>();
listing.add(4);
listing.add(4);
for (int i = 0; i < listing.size(); i++) {
System.out.println(listing.get(i));
}
}
While we can't be sure this is your problem (unless you show us the stacktrace!), it looks like an NPE is likely to occur in this line:
if (!mylist.contains(e)) {
because mylist is never initialized.
In fact, if you are trying to extend ArrayList rather than create a list wrapper, the mylist variable should not exist at all. The list state is in the superclasses private variables. Instead, the add method should probably be written like this:
#Override
public boolean add(E e) {
if (!super.contains(e)) {
return super.add(e); // See note
} else {
return false;
}
}
Note: in general, you should return whatever the superclass returns here. However, when the superclass is ArrayList, we know1 that add will return true, so this is only "saving" a line of code. There might be marginal performance difference, depending on how smart the JIT optimizer is.
1 - We know because the ArrayList.add javadoc specifically states that true is returned.
But this looks like you are trying to create a "set-like" list class. There could be better alternatives; e.g. LinkedHashSet has a defined iteration order, and addition is O(1) rather than O(N). (Admittedly, LinkedHashSet uses a lot more memory, and it has no efficient equivalent to the positional List.get(int) method.)
You got a NullPointerException on this line if (!mylist.contains(e)) { because myList is not instanciated in the default constructor.
public MyArrayList() {
this.myList = new ArrayList<>();
}
But.. you mix inheritance and composition here...
That means add will be applied to myList and get(index) will be applied on this.. So you actually maintain 2 lists here..
In you example myList.contains will always return false because you never add something into. this -> super.add(e) is the same than this.add(e) and it is a different instance of list.
So just removed myList instance field and replace your add like this :
#Override
public boolean add(E e) {
if (!contains(e)) {
add(e);
return true;
} else {
return false;
}
}
Watch out that this class is not thread-safe. Here there is a check-then-act race condition (check = contains(), act = add())
Finally List are designed to allow duplicates... if you don't want duplicates.. just use a Set
I am quite new to Java and I am trying to do my own implementation of a Linked List and then extend that to a Sorted Linked List.
I think my problem is that the SortedLinkedList class that inherits from LinkedList and > dont have access to the private Node start; in the LinkedList. This is a simplification of the code.
I start by creating my own Interface of the List class
interface List<T> {
public int size();
public void add(int pos, T x);
public void add(T x);
public T get(int pos);
public T remove();
}
And saves this as List.java and then I create my linked list class
class LinkedList<T> implements List<T> {
//Starting point of the Linked List
private Node start;
public class Node {
T x;
Node next;
public Node(T x) {
this.x= x;
}
public T getValue(){
return x;
}
}
//Here is implementations of all the methods from List<T> and some ohers
}
This all works as expected, and I have tested all the methods and confirmed that they are working. But now I want to use this class to create another class that inherits from LinkedList and also uses Comparable so I can sort values while I enter them. I get everything set up and creates the class
public class SortedLinkedList<T extends Comparable<T>> extends LinkedList<T>{
//And here I try to do something like
#Override
public void add(T x){
//add logic to add a element
}
}
And here I have tried lots of different things. But no matter how I create the method it wont add any new Nodes. I think the problem have to do with the methods not beeing able to access the private Node start from LinkedList. Becuse I can for instance use the add function from LinkedList to just add a element in the same way by doing
#Override
public void add(T x){
super.add(x);
}
And when I tried to just add the methods from LinkedList directly inside SortedLinkedList and changed it to
public class SortedLinkedList<T extends Comparable<T>>{
}
I did manage to use the compareTo() and Override the add method.
I know this got long, but I hope someone can enlighten me on this. I did try to create a getter and setter method inside LinkedList but I didnt manage to get that to compile in any way without errors.
As the JLS states (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):
Members of a class that are declared private are not inherited by subclasses of
that class. Only members of a class that are declared protected or public are
inherited by subclasses declared in a package other than the one in which the
class is declared.
You're most likely working with private start variable in your add() implementation in LinkedList class.
To resolve the issue just change the access modifier to protected:
protected Node start;
I have to perform similar methods on two types of lists.
private List<WifiConfiguration> wifiConfigurations;
private List<ScanResult> mScanResults;
I need to scan both lists and look for some specific item, so I figured I'll create an interface to wrap them up, and then implement each doesListContains method.
public interface IWifiListWrapper {
boolean doesListContains(IWifiInfo wifiInfo);
// <T> void setList(List<T> wifiList);
}
And one implementation for example is:
public class ScanResultsListWrapper implements IWifiListWrapper {
private List<ScanResult> mScanResults;
#Override
public boolean doesListContains(IWifiInfo wifiInfo) {
...
}
}
That's all good.
Now, I also need to have a setList method to set the list in each of the implementations to their specific List types (WifiConfiguration and ScanResult).
It looks like is should be implemented with Generics somehow, but I am not really sure How do I do it.. I do need to somehow declare each list in the beginning with its Type, correct? so I can pass a matching List type.
How should I go about it?
public interface IWifiListWrapper<T> {
boolean doesListContains(IWifiInfo wifiInfo);
void setList(List<T> wifiList);
}
You can also add restrictions to type like T extends WifiInfo.
public class ScanResultsListWrapper implements IWifiListWrapper<ScanResult> {
private List<ScanResult> mScanResults;
#Override
public boolean doesListContains(IWifiInfo wifiInfo) {
...
}
#Override
public void setList(List<ScanResult> wifiList) {
...
}
}
If I create a class that reads text into an ArrayList. How do I access this ArrayList in other classes? What do I declare the ArrayList as in the class?
Then when I want a different class to access it, how do I go about doing that? I have tried making it static but I still don't know how to access it in other classes.
Declare it as a member e.g.
public class A {
public final List<MyObj> list = new ArrayList<MyObj>();
}
and then
A a = new A();
a.list; // there you go
(note that I've declared it as a List, rather than an ArrayList. That's an implementation issue, and I could simply choose to expose it as a Collection. It's also marked as final since I don't want to change it inadvertently. I can revert that decision later if need be).
It is preferable to make it private and access it via an accessor e.g.
public class A {
private final List<MyObj> list = new ArrayList<MyObj>();
public List<MyObj> getList() {
return list;
}
}
A a = new A();
a.getList();
although someone external to your class could modify it (!). So you could copy it prior to exposing it, or wrap it using Collections.unmodifiableList().
It is better still to hide it completely and ask class A to do something for you (which may involve that list - that's an implementation detail)
public class A {
private final List<MyObj> list = new ArrayList<MyObj>();
public void doSomethingForMe() {
for (MyObj obj : list) {
// do something...
}
}
}
Add a public getter for your list in the class containing it. In the class you want to use the list in, create an instance of class containing the list and get the list by calling the getter method.
class A {
List<String> list = new ArrayList<>();
public List<String> getList() {
return list;
}
}
Class B {
public vois useClassAList() {
A a = new A();
List<String> list = a.getList();
// do what ever you want with the list
}
}
You could return the ArrayList from the class using a get method.
public class A{
//....
public ArrayList<String> getArray(){
return listToReturn;
}
}
therefore you'd only have to call the method and your variable doesnt have to be static:
A a = new A();
a.getArray();
I have a method that takes in a List<> and adds all the numbers in the list together and returns if the number is = 100
My problem is that I want to use the same method for a number of different types of lists
So instead of having this
public boolean checkPercent(List<BarStaff> associates){..same..}
public boolean checkPercent(List<Waiters> associates){..same..}
public boolean checkPercent(List<KitchenStaff> associates){..same..}
I want to have this
public boolean checkPercent(List<could be any type> associates){..same..}
Instead of reusing the same code just of different lists, is there a way to use the same code for all the different types of lists (the staff have the same values in them so they are not different in any way)?
You could use a parameterized method:
public <T> boolean checkPercent(List<T> associates)
{
// snip...
}
or just accept any list:
public boolean checkPercent(List<?> associates)
{
// snip...
}
You may create a generic method:
public <T> boolean checkPercent(List<T> associates) {
... your code ...
}
Use generics:
public <T> boolean checkPercent(List<T> associates){...}
The object-oriented approach would be to have BarStaff, Waiters, and KitchenStaff implement a Employee interface that has a method public int getPercentage().
public boolean checkPercent(List<? extends Employee> associates)
{
foreach (Employee associate in associates)
{
int i = associate.getPercentage();
// rest of code.
}
}