Linked List Constructor with initial value - java

I'm working on a Linked List project, and i'm having a great trouble with the constructor.
i already implemented the default constructor (creates empty list. AKA data = null, size = 0) but the other constructor is really confusing me !!!!
i want to implement a constructor that creates a linked list with valueS/elementS in it (String[]). My first thought was "Piece of cake, all i have to do is :
Use the default constructor to create an empty linked list
Use a for-each loop within a for loop.
The for-each loop is to iterate the string array and add them to my empty linked list.
The for loop is needed to keep a track of the index."
Here is my Code:
public LinkedList(String[] data)
{
LinkedList l = new LinkedList();
for (int i = 0; i <= data.length; i++)
{
for (String d : data)
{
l.add(d, i);
i++;
}
}
}
i tested my code by using this constructor but it does not work.
i know there is a silly mistake somewhere but my logic/mind is blind to see it.

Well you're not really referring to "this" anymore in the constructor you've written. You create a linked list l and modify that one, but you never actually work on "this". Also I agree with the others, the second for loop is unnecessary.
This also lets you use this(), which is a cool functionality to get to know. Helps you keep your code DRY and bug free.
public LinkedList(String[] data){
this(); //Call the default constructor to set up default properties
for (String d : data){
add(d); //Call on this
}
}

You need to change the arguments to the add method, it expects the index to be the first argument. See http://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html#add(int,%20E).
for (String d : data)
{
l.add(i, d);
i++;
}

Another way of doing this would be to just add l.add(d) in the loop. With this new elements are guaranteed to be inserted at the end of the list.
I would use l.add(i, d) when I want to insert specifically at a given location.

Does your class extend LinkedList? If so, here is what I would do:
public class MyLinkedList extends LinkedList<String> {
...
public MyLinkedList(String... array) {
super();
if (array != null && array.length > 0) {
for (String s : array) {
add(s);
}
}
}
...
}
It isn't a great idea to extend LinkedList. If you want an easy way to create a new LinkedList with elements use the following method:
public static <E> LinkedList<E> newLinkedList(
#SuppressWarnings("unchecked") final E... elements) {
final LinkedList<E> list = new LinkedList<E>();
Collections.addAll(list, elements);
return list;
}
....
LinkedList<String> yourList = newLinkedList("foo", "bar", "baz");

Related

best way to Iterate over a collection and array consecutively

Its a very trivial question and related to coding Style and I am just asking to make my coding style more readable
Suppose I have a Collection like linkedList and an Array and I need to iterate over both simultaneously.
currently the best way I know is to get a iterator over list and define a index variable outside the iterator loop and increment the index variable simultaneously to access both next elements {list and array}. Please refer the example below
LinkedList<Integer> list = new LinkedList<Integer>();
Integer[] arr = new Array[25];
// lets suppose both have 25 elements.
// My Iteration method will be
int index =0;
for (Integer val : list) {
System.out.println(val);
System.out.println(arr[index++]);
}
so is it the only way or is there any other way I can perform this iteration in more readable and more relatable manner, where I don't have to take index variable separately.
I know it can be possible that array might have less or more elements than collection but I am only talking about the cases where they have equal and we need to iterate over Both of them.
PS : anybody can write a code that a computer can understand, actual challenge is to write code which humans can understand easily.
What you have is essentially fine: it's simple, and simple can be sufficient to make code readable.
The only thing I would caution about is the side effect of index++ inside arr[index++]: if, say, you want to use the same value multiple times in the loop body, you couldn't simply copy+paste.
Consider pulling out a variable as the first thing in the loop to store the "current" array element (which is essentially what the enhanced for loop does for the list element).
for (Integer val : list) {
Integer fromArr = arr[index++];
// ...
}
Just to point out an alternative without having a separate variable for the index, you can use ListIterator, which provides you with the index of the element.
// Assuming list and are have same number of elements.
for (ListIterator<Integer> it = list.listIterator();
it.hasNext();) {
// The ordering of these statements is important, because next() changes nextIndex().
Integer fromArr = arr[it.nextIndex()];
Integer val = it.next();
// ...
}
ListIterator is not an especially widely-used class, though; its use may in and of itself be confusing.
One of the downsides of the ListIterator approach is that you have to use the it correctly: you shouldn't touch it inside the loop (after getting the values), you have to put the statements in the right order, etc.
Another approach would be to create a library method analogous to Python's enumerate:
static <T> Iterable<Map.Entry<Integer, T>> enumerate(Iterable<? extends T> iterable) {
return () -> new Iterator<T>() {
int index = 0;
Iterator<? extends T> delegate = iterable.iterator();
#Override public boolean hasNext() { return delegate.hasNext(); }
#Override public Map.Entry<Integer, T> next() {
return new AbstractMap.SimpleEntry<>(index++, delegate.next());
}
};
}
This returns an iterable of map entries, where the key is the index and the value is the corresponding value.
You could then use this in an enhanced for loop:
for (Map.Entry<Integer, Integer> entry : enumerate(list)) {
Integer fromList = entry.getValue();
Integer fromArr = arr[entry.getKey()];
}
One option is to have 2 iterators, but I don't think it is any clearer:
for (Iterator<Integer> i1 = list.iterator(), i2 = Arrays.asList(arr).iterator();
i1.hasNext() && i2.hasNext();) {
System.out.println(i1.next());
System.out.println(i2.next());
}
But it is more robust in that it finishes at the shorter of the 2 collections.
I tried to simplify and handle size wise collections where both need not be of the same size. I believe this would work even if the sizes are not same and just one loop would suffice. Code snippet below:
LinkedList<Integer> list = new LinkedList<Integer>();
Integer[] arr = new Array[25];
int maxLength= Math.max(list.size(),arr.size());
//Looping over the lengthy collection( could be Linkedlist or arraylist)
for(int i=0;i<maxLength;i++){
if(list.size()>i)
System.out.println(list[i]);
if(arr.size()>i)
System.out.println(arr[i]);
}
Hope this helps! Thanks

Best way to Iterate collection classes?

Guys i wanna ask about the best way to iterate collection classes ??
private ArrayList<String> no = new ArrayList<String>();
private ArrayList<String> code = new ArrayList<String>();
private ArrayList<String> name = new ArrayList<String>();
private ArrayList<String> colour = new ArrayList<String>();
private ArrayList<String> size = new ArrayList<String>();
// method for finding specific value inside ArrayList, if match then delete that element
void deleteSomeRows(Collection<String> column, String valueToDelete) {
Iterator <String> iterator = column.iterator();
do{
if (iterator.next()==valueToDelete){
iterator.remove();
}
}while(iterator.hasNext());
}
deleteSomeRows(no, "value" );
deleteSomeRows(code, "value" );
deleteSomeRows(name , "value");
deleteSomeRows(colour ,"value" );
deleteSomeRows(size , "value");
THE PROBLEM WITH CODES ABOVE IS THAT IT TAKES AMOUNT OF TIME JUST TO ITERATE EACH OF THOSE CLASSES ? ANY SOLUTION TO MAKE IT FASTER ? pls help if u care :D..
You could simplify your code:
while column.contains(valueToDelete)
{
column.remove(valueToDelete);
}
You're not going to be able to speed up your ArrayList iteration, especially if your list is not sorted. You're stuck at O(n) for this problem. If you sorted it and inserted logic to binary search for the item to remove until it is no longer found, you could speed up access.
This next suggestion isn't directly related to the time it takes, but it will cause you problems.
You should never compare String objects for equality using the == operator. This will cause a comparison of their pointer values.
Use this instead:
if (iterator.next().equals(valueToDelete))
EDIT: The problem here is not the iteration. The problem is removing the elements from the ArrayList. When you remove the first element from an ArrayList, then all subsequent elements have to be shifted one position to the left. So in the worst case, your current approach will have quadratic complexity.
It's difficult to avoid this in general. But in this case, the best tradeoff between simplicity and performance can probably be achieved like this: Instead of removing the elements from the original list, you create a new list which only contains the elements that are not equal to the "valueToDelete".
This could, for example, look like this:
import java.util.ArrayList;
import java.util.List;
public class QuickListRemove
{
public static void main(String[] args)
{
List<String> size = new ArrayList<String>();
size = deleteAll(size, "value");
}
private static <T> List<T> deleteAll(List<T> list, T valueToDelete)
{
List<T> result = new ArrayList<T>(list.size());
for (T value : list)
{
if (!value.equals(valueToDelete))
{
result.add(value);
}
}
return result;
}
}
If you want to modify the collection while iterating them then you should use Iterators, otherwise you can use the for-each loop.
For -each :
// T is the type f elements stored in myList
for(T val : myList)
{
// do something
}
Try putting a break after you find the element to delete.

Add linkedlist to linkedlist, JAVA

I want to design a linkedlist to another linkedlist, so far I have this method in MyLinkedList class:
public void addList(int index, E e){
if(index == 0){
addFirst(e);
} else if (index >= size){
addLast(e);
}
else{
Node<E> current = head;
for(int i = 1; i < index; i++){
current = current.next;
}
Node<E> temp = current.next;
current.next = new Node<E>(e);
(current.next).next = temp;
size++;
}
}
I'm stuck on the method itself, my main program has two LinkedLists that looks like this:
MyLinkedList<String> strings1 = new MyLinkedList<String>();
strings1.add("java");
strings1.add("language");
strings1.add("cooler");
strings1.add("noob");
System.out.println(list1);
MyLinkedList<String> strings2 = new MyLinkedList<String>();
strings2.add("artistic");
strings2.add("cereal");
strings2.add("bowl");
System.out.println(list2);
Then I wanna add the linkedlist of string2 into linkedlist of string1. How would I do that?
I have thought of using
strings1.addList(2, strings2);
but it didn't work, it won't let me add strings2 to strings1
I'm thinking the output would look like this if I have it done:
java, language, artistic, cereal, bowl, cooler, noob
or something similar, please help!
You have a method in your class which accepts a single node, simply call this as many times as you need for the second list:
e.g.
void addAll(int index, MyList<> second_list)
{
for(Object o : second_list)
{
addList(index, o);
++index;
}
}
The above range based for loop may not work unless your class has implemented the proper interfaces, I'm being lazy - use the normal iteration that your class supports...
Easiest possible way....
public void insertList(int index, List<String> list) {
Collections.reverse(list);
for (String str : list) {
add(index, str);
}
}
Use the method addAll(int index, Collection c) to add the two lists together.
strings1.addAll(startIndex, strings2);
You also have to implement the List interface to your class MyLinkedList..
It also isn't really clear what your MyLinkedList class looks like?

Finding number of occurance of an element in a list

Is there a direct way to find out if the list contains duplicates?
Direct API method in some third party utils?
And if the list contains duplicates how many such duplicate elements exist in the list?
Code we can write but I want to know if any direct API exists?
You can count occurrences with
List<T> list =
Map<T, Integer> count = new HashMap<T,Integer>();
for(T t: list) {
Integer i = count.get(t);
if (i == null) i = 0;
count.put(t, i + 1);
}
No you'll have to do it by yourself. But you can use objects that won't allow to insert duplicate data (here)
It looks like you want something like this:
public int getNumOfElementInList(List<Object> myList, Object myElement){
int count = 0;
for(Object element: myList){
if(element.equals(myElement)) //or use instanceof instead, depending
count++;
}
return count;
}
This will give you the number of an element in a list. Alternatively, you could make a List instead of using count, and add the duplicate elements to the List, and return that.
Such as:
public List<DuplicateStats> getTotalNumOfElementInList(List<Object> myList){
List<DuplicateStats> dups = new ArrayList<DuplicateStats>();
int i;
for(Object element: myList){
if((i = dups.indexOf(element) != -1)
dups.get(i).addOne();
else
List.add(new DuplicateStats(element));
}
return count;
}
public class DuplicateStats {
private Object element;
private int count;
public DuplicateStats(Object o){
element = o;
}
public boolean equals(String compare){
return element.toString.equals(compare);
}
public void addOne(){
count++;
}
}
You can add getters, setters, etc. to the class DuplicateStats, but it will keep track of duplicates for you.
If you want an API you can find duplicates with Guava's Multiset.
Just add your list do the set and use the count method.
If you want to find out how many duplicates there are you could keep the list with duplicates, together with a set without duplicates. The number of duplicates is then just the size of the list minus the size of the set.
There are no built-in methods to do this. However you can use LinkedHashSet for example to solve this problem. It does not allow duplicates (as it acts like a set) but it preserves an order of elements (as it acts like a list). You can iterate over all of elements from your list and add them to LinkedHashSet, checking if add method returns true or false.

List of Lists of Lists

I'm new to Java and I need to make a list of lists of lists. I could do it in python because an element of a list can be a list so in an embedded list list[0] would refer to a list and list[0][0] would refer to the zeroeth element of the embedded list. Is there any easy way to implement this behavior in java?
All the other answers are technically correct, but IMHO if you implement a rough List of Lists of Lists you are not treating your data at the right level of abstraction. For example I am pretty sure that a List of Lists already means "something" in your business domain. Encapsulate this "something" in another object so you can just have a List<Something> instead of a difficult to use and maintain List<List<List<Object>>>.
As Mario says, you probably need to abstract out your data a little further. But, the following will do what you need.
In Java you would so something like:
List<List<List<Object>>> listOfListsOfLists =new ArrayList<List<List<Object>>>();
Then to access the items, you would use:
listOfListsOfLists.get(a).get(b).get(c);
Or, to iterate over everything:
for (List<List<Object>> list2: listOfListsOfLists) {
for (List<Object> list1: list2) {
for (Object o: list1) {
// use `o`
}
}
}
Since all of these answers make me barf, can I just add the suggestion that you either
Create a data type to express your data while encapsulating the details of the structure, or at least
Create a key type that wraps an int[] (but overrides equals and hashCode properly) and use a HashMap instead? It's typically rare that your whole 3-dimensional structure will be filled up much anyway.
Even better you could encapsulate that map and use varargs for clean access.
public class NDimensionalArray<V> {
private final int dimensions;
private final Map<Key, V> values = new HashMap<Key, V>();
private NDimensionalArray(int dimensions) {
this.dimensions = dimensions;
}
public V get(int... indices) {
checkIndices(indices);
return values.get(new Key(indices));
}
public void set(V value, int... indices) {
checkIndices(indices);
values.put(new Key(indices), value);
}
private void checkIndices(int[] indices) {
if ( indices.length != dimensions ) {
throw new IllegalArgumentException();
}
}
private static final class Key {
private final int[] indices;
private Key(int[] indices) {
this.indices = indices;
}
#Override
public int hashCode() {
return Arrays.hashCode(indices);
}
#Override
public boolean equals(Object obj) {
return Arrays.equals(indices, ((Key)obj).indices);
}
}
}
If people have examples of established collections libraries that already do this sort of thing, let me know and I'll add links.
While it is certainly true that you can construct a List<List<List<whatever>>> in Java, I can't help but wonder, Why do you want to do this? Not that it's inconceivable that this is the best solution to your problem, but wow, like why?
I guess I could imagine something like
public class Employee ...
List<Employee> store; // all the employees in a store
List<List<Employee>> city; // all the store lists for a city
List<List<List<Employee>>> nation; // all the store lists for the nation
But would you really want to process it that way? I don't know, it depends on what you need to do with it.
A comprehensive example showing List-of-List with collections and generics (Java 1.5+)
// declare the list of lists
List<List<String>> listOfListOfStrings = new ArrayList<List<String>>();
// populate
List<String> listOfStrings = new ArrayList<String>(); // one inner list
listOfStrings.add("one-one");
listOfStrings.add("one-two");
listOfListOfStrings.add(listOfStrings);
listOfStrings = new ArrayList<String>(); // and another one
listOfStrings.add("two-one");
listOfStrings.add("two-two");
listOfListOfStrings.add(listOfStrings);
// access
String oneOne = listOfListOfStrings.get(0).get(0); // first element of first inner list
String twoTwo = listOfListOfStrings.get(1).get(1); // second element of second inner list

Categories

Resources