views:

191

answers:

1

Hi,

It's been two years since I last coded something in Java so my coding skills are bit rusty.

I need to save data (an user profile) in different data structures, ArrayList and LinkedList, and they both come from List. I want to avoid code duplication where I can and I also want to follow good Java practices.

For that, I'm trying to create an abstract class where the private variables will be of type List<E> and then create 2 sub-classes depending on the type of variable.

Thing is, I don't know if I'm doing this correctly, you can take a look at my code:

Class: DBList

import java.util.List;

public abstract class DBList {

    private List<UserProfile> listName;
    private List<UserProfile> listSSN;

    public List<UserProfile> getListName() {
    return this.listName;
    }

    public List<UserProfile> getListSSN() {
    return this.listSSN;
    }

    public void setListName(List<UserProfile> listName) {
    this.listName = listName;
    }

    public void setListSSN(List<UserProfile> listSSN) {
    this.listSSN = listSSN;
    }

}

Class: DBListArray

import java.util.ArrayList;

public class DBListArray extends DBList {

    public DBListArray() {
    super.setListName(new ArrayList<UserProfile>());
    super.setListSSN(new ArrayList<UserProfile>());
    }

    public DBListArray(ArrayList<UserProfile> listName, ArrayList<UserProfile> listSSN) {
    super.setListName(listName);
    super.setListSSN(listSSN);
    }

    public DBListArray(DBListArray dbListArray) {
    super.setListName(dbListArray.getListName());
    super.setListSSN(dbListArray.getListSSN());
    }

}

Class: DBListLinked

import java.util.LinkedList;

public class DBListLinked extends DBList {

    public DBListLinked() {
    super.setListName(new LinkedList<UserProfile>());
    super.setListSSN(new LinkedList<UserProfile>());
    }

    public DBListLinked(LinkedList<UserProfile> listName, LinkedList<UserProfile> listSSN) {
    super.setListName(listName);
    super.setListSSN(listSSN);
    }

    public DBListLinked(DBListLinked dbListLinked) {
    super.setListName(dbListLinked.getListName());
    super.setListSSN(dbListLinked.getListSSN());
    }

}

1) Does any of this make any sense? What am I doing wrong? Do you have any recommendations?

2) It would make more sense for me to have the constructors in DBList and calling them (with super()) in the subclasses but I can't do that because I can't initialize a variable with new List<E>().

3) I was thought to do deep copies whenever possible and for that I always override the clone() method of my classes and code it accordingly. But those classes never had any lists, sets or maps on them, they only had strings, ints, floats. How do I do deep copies in this situation?

+3  A: 

You shouldn't need subclasses that takes LinkedList<UserProfile> and ArrayList<UserProfile> to begin with. Working with List<UserProfile> is more than fine, it's recommended (see Effective Java 2nd Edition, Item 52: Refer to objects by their interfaces).

Do keep in mind that LinkedList<E> implements List<E>, and ArrayList<E> implements List<E>, so if you take a List<E>, you can take both LinkedList<E> and ArrayList<E> already (and all other implementors of List<E> out there).


Regarding clone()

It's well understood now that clone() is deeply broken in Java, and should not be used (see Effective Java 2nd Edition, Item 11: Override clone judiciously).

From an interview with author Josh Bloch:

If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken [...] There are very few things for which I use Cloneable anymore [...] It's a shame that Cloneable is broken, but it happens.

Related questions

polygenelubricants
So, you're saying that if I pass a `LinkedList<>` or a `ArrayList<>` into `DBList` constructor (if the constructor takes `List<>` as argument) is enough to differentiate them? It's because they are basically the same, just the internal memory implementation is different?
Nazgulled
@Nazgulled: why do you need to distinguish them? Is it not sufficient to just work on a `List<E>`, regardless of the implementation?
polygenelubricants
I'll also need to do something similar but for `Map<K,V>` and then have a `TreeMap<K,V>` and a `HashMap<K,V>`. Should I just use `Map<K,V>` in this situation?
Nazgulled
What I meant about distinguish them was if using `List<E>` was enough to make the implementations different. I really need one to be `LinkedList` and the other `ArrayList`. Sorry, but like I said, my Java is very rusty.
Nazgulled
@Nazgulled: Why do you need two implementations? How will they differ? Is it only in that one uses a `LinkedList` and the other uses `ArrayList` and that's it, or are there algorithmic differences depending on the implementation? Are you sure those algorithms aren't already implemented in the framework? There's a `RandomAccess` marker interface that is implemented by `ArrayList`, and many utility methods already take advantage of it.
polygenelubricants
@Nazgulled: you mentioned `Map` and having subclasses that takes `HashMap` and `TreeMap`, etc. What about `Hashtable`? `EnumMap`? `WeakHashMap`? These are all `Map` implementations. Do you need to treat them specially too? Why? And if not, then why the special two to begin with?
polygenelubricants
No, I don't need those, I only need `ArrayList`, `LinkedList`, `HashMap` and `TreeMap`. My project is to use those data structures and to hold user profiles (the same user profiles for each data structure). The idea is to measure the time it takes to perform some operations with different data structures. Those 4 are the ones requested by my instructor.
Nazgulled
@Nazgulled: then implement a concrete class that takes `List`, and instantiate it twice, once with `ArrayList`, and another with `LinkedList`, and compare. You don't need two separate classes.
polygenelubricants
Ok :) The same for Map right?
Nazgulled
@Nazgulled: the way I understand the problem, yes.
polygenelubricants