Adding a number into a LinkedList, inside an ArrayList - java

I'm trying to add an integer into a LinkedList; however, I'm not sure how to add the integer to an already existing LinkedList.
class HashChaining extends HashTable {
private ArrayList<LinkedList<Integer>> chains;
private HashFunction function;
HashChaining (Hashfunction function) {
this.function = function;
this.chains = new ArrayList<>(capacity);
for (int i=0; i<capacity; i++)
chains.add(i, new LinkedList<>());
}
void insert(int key) {
int location = function.apply(key);
chains.add(location, new LinkedList<Integer>(chains.get(location).push(key)));
}

If you take a look at javadoc, you'll see, that a method add​(int index, E element) inserts an elements at a given index. What you want to achieve is to add an element to an inner-list:
chains.get(location).add(key)
chains.get(location) will retrieve an inner LinkedList on a position given by location, then into this list, you can add your element.

Related

How to create arraylist without one element from another arraylist

I needed to create an arraylist without an element of another arraylist, but I need this new arraylist to keep updating. For example, an element of the old arraylist is removed, also remove in the new one.
But I did not want to remove the element of the two arraylist, only the old one, so as not to have much code
(My method "showPeople" is updated every 1 second)
My code:
ArrayList<Person> personList = new ArrayList<>();
private void method(){
personList.add(new People("Name"))
}
private void showPeople(){
ArrayList<Person> newPersonList =
new ArrayList<>(personList.stream()
.filter(person -> !person.getName().equals("Test"))
.collect(Collectors.toList()))
for (int i = 0; i < newPersonList.size(); i++){
gui.show(newPersonList.get(i).getName());
}
}
The problem is that when I create the new arraylist and remove an item from the old one, the new one does not update
You're making multiple copies of your list; instead, do something like:
List<Person> filterPeople(List<Person> people, #NotNull String name) {
return people.stream()
.filter(person -> !name.equals(person.getName()))
.collect(Collectors.toList());
}
If you're uncomfortable with the lack of guarantees on the the shape of the List, you can be explicit:
.collect(Collectors.toCollection(ArrayList::new));
It's still unclear what you're asking, however. I suggest you provide a minimal, complete, and verifiable example.
If you want the list without the element to keep updating, you can create a view of the list by extending AbstractList.
The API documentation contains instructions as to the methods you would need to override. If you don't want the list to be modifiable through the view, all you need to do is to override the get and size methods:
class ListView extends AbstractList<String> {
private final List<String> delegate; // Initialize in constructor.
public T get(int i) {
int pos = delegate.indexOf("Test");
if (pos < 0 || i < pos) return delegate.get(i);
return delegate.get(i + 1);
}
public int size() {
return delegate.size() - (delegate.contains("Test") ? 1 : 0);
}
}
This will repeatedly search for the "Test" element, because there is no way for the view to know if the delegate list has been updated underneath it.
Here's a handy method:
private static <T> List<T> CopyListWithoutItem(List<T> listToCopy, T itemToNotCopy) {
return listToCopy.stream().filter(item -> !item.equals(itemToNotCopy)).collect(Collectors.toList());
}
You can use that: List<String> elements = list.stream().distinct().collect(Collectors.toList());
That will remove duplicates.

Reverse LinkList whilst preserving original nodes

My teacher has assigned a program where I am to create a linked list of some random numbers. I am to create it from a list and then the second part of the assignment is to reverse it. The actual quote is
Write a Java method called reverseLinkedList() that will generate a
reversed linked-list from the linked-list that you create in problem
1. Your method should accept a linked-list as an input and return another linked list that has the node references in the reversed
order. Please do not print the original list in reverse. The idea is
to manipulate the node references so that the nodes are preserved in
same in order as they were originally created.
The code I have generated so far looks like
import java.util.*;
public class progassignment2
{
public static void main(String args[])
{
List<Integer> myList = new ArrayList<Integer>();
Random ran = new Random();
int ranNum;
for(int x = 0;x<5;x++)
{
ranNum = ran.nextInt(500);
myList.add(x,ranNum);
}
LinkedList<Integer> mylinklist = createLinkedList(myList);
System.out.println(mylinklist);
LinkedList<Integer> mylinklistrev = reverseLinkedList(mylinklist);
}
public static LinkedList createLinkedList(List<Integer> integerList)
{
LinkedList<Integer> linkedlist = new LinkedList<Integer>();
linkedlist.addAll(integerList);
return linkedlist;
}
public static LinkedList reverseLinkedList(LinkedList inputList)
{
for(int y = 0;y < inputList.size();y++)
{
inputList.addLast(inputList.pollFirst());
}
return inputList;
}
}
However I don't think I'm doing the assignment correctly, or that I understand what he is asking of me and unfortunately won't answer any questions and just cites "Read the assignment". Any help is greatly appreciated
What about:
public static LinkedList reverseLinkedList(List<Integer> inputList) {
LinkedList<Integer> reversedLinkedlist = new LinkedList<Integer>(inputList);
Collections.reverse(reversedLinkedlist);
return reversedLinkedlist;
}
Usually, exercises on linked lists do not make use of any built-in Java collection (like ArrayList, LinkedList, etc), but are instead meant to make you build your own collection type.
Your teacher probably wants you to build a very basic element, which would then become the building block of your own collection type: imagine an object where you can store a value and a reference to the following value in the list. In code:
class Node {
private int value;
private Node next;
public Node(int value){
this.value = value;
}
public int getValue(){
return value;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
Each element points to the next one, and the end of the list is marked by the last node's next element being null.
By using objects like this, you'll be able to define your own linked list, without using any pre-defined Collection offered by Java.
You've surely heard about the stack data structure: by reading all the elements in your linked list and putting them inside a stack, once the list will be over, you're going to fetch the elements inside the stack; creating a linked list in the order of the elements pulled from the stack will solve your problem of inverting the linked list.
The idea is to manipulate the node references so that the nodes are
preserved in same in order as they were originally created.
You should create your own LinkedList. You are not allowed to use common ways of reversing like using recursion, stack ,modifications or any collections interface methods.
here is the link includes LinkedList reversing ways and solution:
class LinkedList {
Node head; // head of list
/* Linked list Node */
class Node {
int data;
Node next;
Node(int d) {
data = d;
next = null;
}
}
/* Function to print reverse of linked list */
void printReverse(Node head) {
if (head == null)
return;
// print list of head node
printReverse(head.next);
// After everything else is printed
System.out.print(head.data + " ");
}
/* Inserts a new Node at front of the list. */
public void push(int new_data) {
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
public static void main(String args[]) {
LinkedList llist = new LinkedList();
llist.push(4);
llist.push(3);
llist.push(2);
llist.push(1);
llist.printReverse(llist.head);
}
}

implementing linked list using arrays

I am trying to implement a linked list in java using arrays as the underlying structure. However, I am not sure how to do insert an element in the array after an element and shift the array down by one
class linkedList{
char data[];
int next;
//constructor
public linkedList(int MAX){
data = new char[MAX];
}
public void insertFirst(char d){
if(data[next]==0){
data[next] = d;
next++;
}
else{
System.out.println("list is full");
}
}
public void insertAfter (char after ,char value){
next=0;
while(data[next] !=after){
next++;
}
char temp = data[next+1];
data[next+1] = value;
}
public void printList(){
for(int i=0;i<data.length;i++){
System.out.print(data[i]);
}
}
}
public class myLinkedList {
public static void main(String args[]) {
linkedList list = new linkedList(9);
list.insertFirst('T');
list.insertFirst('H');
list.insertFirst('L');
list.insertAfter('H', 'z');
list.printList();
}
}
Also would this be considered a linked list?
This is not a linked list. What you have is similar to an ArrayList, in that an array is used as the underlying data structure. A linked list is composed of a series of nodes, with each node linked to the next. The linked list is traversed by calling something like node.next() on the current node until the target or the end of the list is reached.
If you want to insert another element into your list structure after reaching the size limit, you will need to create a new array, copy the contents of the old array over, and insert the new element into the array. You can use System.arraycopy() to perform the copying or to shift items within the array.

Adding elements to ArrayList in java

import java.util.ArrayList;
public class ArrayTest {
private static ArrayList<String> list = new ArrayList<String>();
public static void printList () {
System.out.println("Printing the list");
for (int i = 0; i < list.size(); i++)
{
if (list.get(i) != null)
System.out.println(i + " => " + list.get(i));
}
}
public static void add(Integer index, String val) {
while(list.size() <= index)
list.add(null);
list.add(index, val);
}
public static void main(String[] args) {
ArrayTest.add(8, "cover");
ArrayTest.printList();
ArrayTest.add(6, "and");
ArrayTest.printList();
}
}
produces the following output
Printing the list
8 => cover
Printing the list
6 => and
9 => cover
The add(Integer index, String val) function adds an appropriate number of nulls to the list as a check to avoid any IndexOutOfBoundsException exceptions.
Can someone explain why does adding "and" to the list push "cover" a position further in the list ?
Because the add method you used inserts an element at specified index. It doesn't replace the existing element at this position, it add a new, so add the index position from that towards the end.
If you need to replace the value, use the set method.
Because this is the actual specification of the List.add(int index, E element) method:
Inserts the specified element at the specified position in this list
(optional operation). Shifts the element currently at that position
(if any) and any subsequent elements to the right (adds one to their
indices).
As to "why": this is done to avoid overwriting the element on the specified position.
In Java 9, there's an easy way with less number of lines without needing to initialize or add method. Use collection factory methods:
List<String> list = List.of("first", "second", "third");

Insert array into correct location of arraylist of int arrays

Overview
I have an arrayList that holds multiple int arrays that have two parameters, key and value. (I know there exists a map library, but for this task I wish to use an arrayList).
Imagine my arrayList has the following arrays:
[3, 99][6, 35][8, 9][20, 4][22, 13][34, 10]
As you can see, they are in order by the index, which is done when I first add them to the arrayList.
My problem
if I want to add an array to this arrayList it would appended to the end of the list, whereas I want to add it to the correct position in the list.
I'm fairly new to arrayLists, and as such was wondering if there exists an elegant solution to this problem that I have not come across.
Current thoughts
Currently, my solution would be to iterate over the arrayList, then for every array temporally store the key (array[0]), I would then iterate over again and add my array in the correct position (where it's key is in-between two other keys).
Your idea of iterating through is correct; however there is no need to perform the iteration twice. Finding the right index and inserting the element can be done in one loop. ArrayList has a method add(int, E) that can insert an element into any position in the list. Try this:
//the value you want to insert
int[] toInsert = {someValue, someOtherValue};
//assume theList is the list you're working with
for(int index = 0; index < theList.size() -1; index ++)
{
int key = theList.get(index)[0];
int nextKey = theList.get(index + 1)[0];
//if we've reached the correct location in the list
if (toInsert[0] > key && toInsert[0] < nextKey)
{
//insert the new element right after the last one that was less than it
theList.add(index + 1,toInsert);
}
}
Note that this method assumes that the list is sorted to begin with. If you want to make that a guarantee, look into some of the other answers describing sorting and Comparators.
It may be more elegant to produce a class to hold your two values and ensure that implements Comparable, as shown below:
public class Foo implements Comparable<Foo> {
private int x; // your left value
private int y; // your right value
// Constructor and setters/getters omitted
public int compareTo(Foo o) {
return Integer.compare(x, o.getX());
}
}
Then add and sort as follows:
List<Foo> listOfFoos = new ArrayList<Foo>;
// ...
listOfFoos.add(new Foo(33,55));
Collections.sort(listOfFoos);
That would be the most readable solution. There may be faster options, but only optimise if you can prove this part is a bottleneck.
First Option
If you want to be able to sort your array you should be storing Comparable Objects.
So, you can create a Class that will hold your two value array and implement the Comparable interface.
If you chose this option, after adding the element all you need to do is to call .sort() on your List.
Second Option
You can define Comparator that you can use for sorting. This would be reusable and would allow you to keep your two dimensional arrays. You will also have to sort after each time you add.
Third Option
You could define your Comparator on the fly as shown in this particular question:
Java Comparator class to sort arrays
you can do the following:
import java.util.ArrayList;
public class AddElementToSpecifiedIndexArrayListExample {
public static void main(String[] args) {
//create an ArrayList object
ArrayList arrayList = new ArrayList();
//Add elements to Arraylist
arrayList.add("1");
arrayList.add("2");
arrayList.add("3");
/*
To add an element at the specified index of ArrayList use
void add(int index, Object obj) method.
This method inserts the specified element at the specified index in the
ArrayList.
*/
arrayList.add(1,"INSERTED ELEMENT");
System.out.println("ArrayList contains...");
for(int index=0; index < arrayList.size(); index++)
System.out.println(arrayList.get(index));
}
}
/*
Output would be
ArrayList contains...
1
INSERTED ELEMENT
2
3
*/
There is also a version of add that takes the index at which to add the new item.
int i;
for(i=0; i<arr.size(); i++){
if(arr.get(i)[0] >= newArr[0]){
arr.add(i, newArr);
}
}
if(i == arr.size())
arr.add(i, newArr)
Use a Comparator of int[] along with binarySearch :
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class Main
{
public static void main(String[] argv)
{
ArrayList<int[]> list = new ArrayList<int[]>();
list.add(new int[] { 3, 99 });
list.add(new int[] { 6, 35 });
list.add(new int[] { 8, 9 });
list.add(new int[] { 20, 4 });
list.add(new int[] { 22, 13 });
list.add(new int[] { 34, 10 });
Compar compar = new Compar();
addElement(list, new int[] { 15, 100 }, compar);
for(int[] t : list)
{
System.out.println(t[0]+" "+t[1]);
}
}
private static void addElement(ArrayList<int[]> list, int[] elem, Compar compar)
{
int index = Collections.binarySearch(list, elem, compar);
if (index >= 0)
{
list.add(index, elem);
return;
}
list.add(-index - 1, elem);
}
static class Compar implements Comparator<int[]>
{
#Override
public int compare(int[] a, int[] b)
{
return a[0] - b[0];
}
}
}

Categories