Implementing a Set in Java using a LinkedList - java

I have to create a class named Myset which includes methods like IsEmpty(), Insert(Object O) etc. I thought to use a Linked list of objects to implement the Myset class. But as I am new to Java, I am stuck with creating the object itself i.e. I am not clear even how to start with. I thought of something like this:
public class Myset {
LinkedList<Object> LL = new LinkedList<Object>();
}
I further have to write a method: public Myset Union(Myset a): Returns a set which is the union of the current set with the set a. This can be done by iterating through a, if the element at a particular index in a is not contained in LL then we add that element to LL. But how do I write this in a Java code? PS: This is an assignment question and we aren't allowed to use Sets implementation.

Some starting points.
You should either use "true" generics:
class MySet<T> {
private final LinkedList<T> objects = new LinkedList<T>();
or leave generics completely out, like:
class MySet {
private final LinkedList objects = new LinkedList();
You see, your solution
LinkedList<Object> LL = new LinkedList<Object>();
will allow that the user can store any kind of object in your set. So, first a String, then an Integer, and so on. Most likely, that is not what you had in mind. In general, collections in Java are about a specific sort of objects, like only Strings, or only Integer objects.
( side note: LL is a bad name for a field - so study java naming guide lines for that, too )
But there is even less sense in use <Object>. That is like using generics without using them at the same point.
And now, that you have a MySet class, you start one by one:
You add a constructor that allows instantiating an object of your class
You add methods (one by one!) that allow reasonable interaction with your class
Thing is: start slowly. Dont try to solve the big things upfront. Instead: just make sure that your class works as Set; so you can add things, you can check that they are in; and so on.
And only when all of these basic things work you should go forward and add stuff like "union".

A linked list doesn't give you any benefit for a general set. You could simply use an object array, ArrayList, Vector etc. instead, as you would have to compare each element to another specific element anyway. If you insert an element, you have to make sure, there isn't already one in it (this is part of the mathematical definition of a set), just as you have to make this sure in unions, intersections and set differences. This means you have to implement comparability, so you should use the Comparable interface instead of Object, too.

Related

Interface with concrete classes [duplicate]

This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
If we consider two implementations below, what's the actual use of the first one?
List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
From what I have read in the posts, the first implementation helps in avoiding breaking change like we can change the implementation again as
a=new TreeList<String>();
But I don't understand whats the actual use of changing the implementation with treelist as we can use only the List interface methods?
But I don't understand whats the actual use of changing the implementation with treelist as we can use only the List interface methods?
Different implementations of interface List have different performance characteristics for different operations. Which implementation of List you should choose is not arbitrary - different implementations are more efficient for different purposes.
For example, inserting an element somewhere in the middle is expensive on an ArrayList, but cheap on a LinkedList, because of the way the implementations work. Likewise, accessing an element by index is cheap on an ArrayList, but expensive on a LinkedList.
It may happen that when you started writing your program, you used an ArrayList without thinking about it too much, but later you discover that a LinkedList would be more efficient.
When you've programmed against the interface List instead of a specific implementation, it's very easy to change from ArrayList to LinkedList - to the rest of the program, it still looks like a List, so you'd only have to change one line.
Lets say that you have decided to develop a more efficient List implementation of your own. Perhaps one that has better memory management internally, or may be a faster set method (insertion) implementation. You can just implement the List interface and rest of your code will continue to work without any change, except this one line. You can also extend ArrayList and write your own code.
//Old code
List<String> a = new ArrayList<String>();
a.set(0, "Test");
//New code
List<String> a = new MyCustomisedList<String>();
//Same code, but your optimized set logic. May be faster...
a.set(0, "Test");
A TreeList doesn't exist, so lets use a PersistentList as an example.
Lets say you have an #Entity that you want to save to a database:
public class MyMagicEntity {
#OneToMany
List<MyChildEntity> children;
public void setChildren(final List<MyChildEntity> children) {
this.children = children;
}
}
Now, when you create MyMagicEntity then you would do something like
final MyMagicEntity mme = new MyMagicEntity();
final List<MyChildEntity> children = new ArrayList<>();
children.add(new MyChildEntity("one"));
children.add(new MyChildEntity("two"));
children.add(new MyChildEntity("three"));
mme.setChildren(children);
//save to DB
So you created an ArrayList that you passed into your MyMagicEntity, which assigns it to the List - it doesn't care that the underlying implementation is as long as it's a List.
Now, later you do:
final MyMagicEntity mme = //load from DB
final List<Children> children = mme.getChildren();
So, what is children? Well, if we are using JPA and Hibernate it is actually a PersistentList, not an ArrayList.
As we access the members of children, Hibernate will go and pull them from the database. This List is still a List - your program doesn't have to know any of this.
Could you do this without using the List interface? No! Because:
you cannot create a PersistentList
Hibernate cannot create an ArrayList
Whilst this is an extreme example, where the underlying behaviour of the List is completely different, this applies in all sorts of other situations.
For example:
ArrayList and LinkedList have different performance characteristics, you may want to switch
Guava has an ImmutableList which you may want to use
Collections.unmodifyableList also implements List, which you may want to use
You could conceivably have a List backed by a file
The basic idea is that List defines what any list must be able to do, but not how it is done.
Here List is an Interface which contains all common operation method can perform with an List.
List Interface is parent for ArrayList , LinkedList and many more class. So, It can hold all these type of Object reference.
All these List method have different (or own type) Implementation with different class. So, whatever method you use will automatically apply according to override method definition of Object belong to the class.
List<String> a= new ArrayList<String>();
ArrayList<String> b= new ArrayList<String>();
Now , In Your case you can declare both ways is alright. but suppose a Scenario like this.
You are calling some services and you know that return any List Type (not specific) of Object. It may be a LinkedList or ArrayList or any other type of List.
at that time whatever response you get You can easily hold those responses in a List Type of Reference Variable.
and after gathering the result you can differentiate further of Object Type.

Should I implement List interface or extend ArrayList class

I am developing an application where as a background I need to monitor the user activity on particular objects and later when they are visualized they need to be sorted based on the order of which the user used them ( the last used object must be visualized on the first row of a grid for example.)
So if I have an ArrayList where I store the objects which the user is dealing with in order to add the last used object I need to check if it is already in the list and then move it at the first position. If the object is not there I simply add it at the first position of the list.
So instead of doing all these steps I want to make my own list where the logic explained above will be available.
My question is which scenario is better:
Implement the list interface
Extend the ArrayList class and override the ADD method
Create a class that contains an ArrayList and handles any additional functionality.
I.e. prefer composition over inheritance (and in this case, implementing an interface). It's also possible to have that class implement List for relevant cases and just direct the (relevant) operations to the ArrayList inside.
Also note that LinkedHashMap supports insertion order (default) and access order for iteration, if you don't need a List (or if you can suitably replace it with a Map).
So instead of doing all these steps i want to make my own list where
the logic explained above will be available.
I would try to refactor your design parameters (if you can) in order to be able to use the existing Java Collection Framework classes (perhaps a linked collection type). As a part of the Collections Framework, these have been optimized and maintained for years (so efficiency is likely already nearly optimal), and you won't have to worry about maintaining it yourself.
Of the two options you give, it is possible that neither is the easiest or best.
It doesn't sound like you'll be able to extend AbstractList (as a way of implementing List) so you'll have a lot of wheel reinvention to do.
The ArrayList class is not final, but not expressly designed and documented for inheritance. This can result in some code fragility as inheritance breaks encapsulation (discussed in Effective Java, 2nd Ed. by J. Bloch). This solution may not be the best way to go.
Of the options, if you can't refactor your design to allow use of the Collection classes directly, then write a class that encapsulates a List (or other Collection) as an instance field and add instrumentation to it. Favor composition over inheritance. In this way, your solution will be more robust and easier to maintain than a solution based on inheritance.
I think LinkedHashMap already does what you need - it keeps the elements in the order they were inserted or last accessed (this is determined by the parameter accessOrder in one of the constructors).
https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html
EDIT
I don't have enough reputation to comment, so I'm putting it here: You don't actually need a map, so Venkatesh's LinkedHashSet suggestion is better.
You can do something like this:
<T> void update(Set<T> set, T value) {
set.remove(value);
set.add(value);
}
and then
LinkedHashSet<String> set = new LinkedHashSet<>();
update(set, "a");
update(set, "b");
update(set, "c");
update(set, "a");
Iterator<String> it = new LinkedList<String>(set).descendingIterator();
while (it.hasNext()) {
System.out.println(it.next());
}
Output:
a
c
b
You might try using HashMap<Integer, TrackedObject> where TrackedObject is the class of the Object you're keep track of.
When your user uses an object, do
void trackObject(TrackedObject object)
{
int x = hashMap.size();
hashMap.add(Integer.valueOf(x), object);
}
then when you want to read out the tracked objects in order of use:
TrackedObject[] getOrderedArray()
{
TrackedObject[] array = new TrackedObject[hashMap.size()];
for(int i = 0; i < hashMap.size(); i++)
{
array[i] = hashMap.get(Integer.valueOf(i));
}
return array;
}
A LinkedHashSet Also can be helpful in your case. You can keep on adding elements to it, it will keep them in insertion order and also will maintain only unique values.

Selecting specific object(s) from list with Java

Probably some basic stuff I am missing here, but what is the best way to select objects matching some criteria from list?
Say we have:
class MyObject {
int id;
String type;
// getters..setters
}
I use it:
List<MyObject> myObjects = new ArrayList<MyObject>();
myObjects = getListOfObjects();
Now lets say that in the myObjects there are 10 items and 3 of them have type=="bla". At the moment I am just looping thru all the objects and within the loop decide if I want it or not, but is there a better way?
I remember that in C# I used to have something like
myObjects.Where(x => x.type.equals("bla"));
PS, I am targeting Java 7 so no lambda for me yet.
I don't think you can do this without creating an index of some kind. So e.g. having Map<String, Map<String, Set<MyObject>>> you could then call index.get("type").get("bla"). But you would have to first construct this structure. This would be useful if a) there are no changes to the properties AND b) you have a LOT of objects. For 10 objects the performance is of no concern here and I would simply just do what you're doing right now and hide it inside some nice handy method.
You could use the LambdaJ library and its Lambda.exists method with some custom Hamcrest matcher. Then you could make your main code look like this:
if (exists(myObjects, typeIs("bla"))) { /* ... */ }
...provided that you create that custom matcher method typeIs by yourself. But I wouldn't go down this way if I had just one place with just 10 items in a list.
It also depends on your data: if your list is sorted, you could do a binary search on it. That's more useful if you have thousands of items in the list, though.
Finally, you could just use Collection.contains: myObjects.contains(blaElement), but that requires that the blaElement has such an equals method that returns "true" when the type matches.

How should I implement a list in of lists in Java? Or is there a better way than a list of lists?

I'm trying to make a variable offsets which equals ((2,1),(2,-1),(1,-2)) through which I can iterate and get the X,Y coordinates for each position.
In python, I would just use a list of lists. I thought I would be able to do this in Java, too, but it seems much more difficult to do so with this language...
I though maybe int[] offsets would work, but no dice, apparently. Then, as it's a list of lists (not just a list), I tried int[][] offset and eclipse still thought I was a moron.
What am I missing? Or am I just making this harder than it needs to be, and there's actually some really simple thing you'd suggest instead of a list of lists?
The best idea would be to use Point
Point point = new Point(1,4);
List<Point> points = new ArrayList<Point>();
Another way is to use list of lists. Not recommended. Not object oriented
List<List<Integer>>
Alternatively you can create your version of Point class. For example an object which will have one axis inside
class AxisX{
private List<Integer>
}
And put it inside another object
class Coordinates{
private List<AxisX>
}
from what's written here, it looks like you're trying to access list members with array syntax.
In java, collections and arrays have completely different syntax.
arrays are indexed with [], collections such as lists use methods.
so to get the i'th element of the j'th list
list.get(j).get(i);
the first get call returns the list at the i'th index of list
the second get call, returns the j'th element of the inner list.
though for this case, I'll second #Tom_G and suggest using something like a point object
then you only need one list, the point handling x, y coordinates in a single object.
if you will use this in something related to serialization and remote data transfer, try using the implementer classes of List, and not List itself (while declaring your variable), so not to get stuck in the middle, like
ArrayList<ArrayList<Integer>> ....
because the Collections framework interfaces dont extend the Serializable interface
maybe this helps, becuase i lived a horrible experience because i didnt notice this from the start

Java data structures (simple question)

Say I want to work with a linked list in java. I thought that the best way to create one is by:
List list = new LinkedList();
But I noticed that this way I can only use methods on the list that are generic. I assume that the implementation is different among the different data structures.
So if I want to use the specific methods for linked list, I have to create the list by:
LinkedList list = new LinkedList();
What's the main reason for that?
Tnanks.
List is an interface that abstracts the underlying list implementation. It is also implemented by e.g. ArrayList.
However, if you specifically want a LinkedList, there is nothing wrong with writing LinkedList list. In fact, if you just pass it around as a list, people may (not knowing the implementation) unknowingly write algorithms like:
for(int i = 0; i < list.size(); i++)
{
// list.get(i) or list.set(i, obj)
}
which are linear on a random access list (e.g. ArrayList) but quadratic on a LinkedList (it would be preferable to use a iterator or list iterator). Java provides the RandomAccess marker interface so you can distinguish.
Of course, you can call these methods on a reference of type LinkedList too, but people should be more likely to consider the cost.
As a note, in .NET LinkedList does not implement IList for this reason.
The first idiom allows you to change the runtime type that list points to without modifying any client code that uses it.
What methods in LinkedList do you think you need that aren't in List? You can always cast for those.
But the whole idea behind interfaces is to shield clients from how the interface is implemented.
If you really need a LinkedList, so be it. But I prefer the first idiom, because most of the time I really just need List methods.
Every LinkedList is a List, too. That also means that you can do everything with a LinkedList that you can do with a List and that you can store a LinkedList as List. However, when you store it as List, you can only call methods of the LinkedList that a List also has.
By the way: This is not Generics. Generics are like this:
LinkedList<String> list = new LinkedList<String>();
List list = getSomeList();
Here you're saying that it's a list. You have no idea whether or not it's a LinkedList or an ArrayList or whatever. It is an abstract thing (I assume you mean "abstract" by the word "generic", since generics are a different thing entirely). Thus you can't treat it like it's an LinkedList -- you have to treat it like it's a List (which it is).
The fact that "you know" that it's a LinkedList is all well and good, and you can safely cast if you need to do it. But it might help to tell the compiler that it's a LinkedList, by declaring it as so, if it's always going to act as a LinkedList.

Categories

Resources