com.github.andyshao.data.structure.DoubleLinked Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Gear Show documentation
Show all versions of Gear Show documentation
Enhance and formating the coding of JDK
The newest version!
package com.github.andyshao.data.structure;
import java.io.Serial;
import java.io.Serializable;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Function;
/**
*
* Title:Double Linked interface
* Descript:
* Copyright: Copryright(c) Feb 9, 2015
* Encoding:UNIX UTF-8
*
* @author Andy.Shao
*
* @param data
*/
public interface DoubleLinked extends Linked>, Serializable {
/**
* Double linked element
* @param data type
*/
public interface DoubleLinkedElmt extends Linked.LinkedElmt>, Serializable {
/**
* Get default {@link DoubleLinkedElmt}
* @param data data
* @return {@link DoubleLinkedElmt}
* @param data type
*/
public static DoubleLinkedElmt defaultElmt(DATA data) {
DoubleLinkedElmt result = new DoubleLinkedElmt() {
@Serial
private static final long serialVersionUID = -107307947887970784L;
private DATA data;
private DoubleLinkedElmt next;
private DoubleLinkedElmt prev;
@Override
public DATA data() {
return this.data;
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
DoubleLinkedElmt that;
if (obj instanceof DoubleLinkedElmt) {
that = (DoubleLinkedElmt) obj;
return Objects.equals(this.data() , that.data()) && Objects.equals(this.next() , that.next()) && Objects.equals(this.getPrev() , that.getPrev());
} else return false;
}
@Override
public DoubleLinkedElmt getPrev() {
return this.prev;
}
@Override
public int hashCode() {
return Objects.hash(this.data() , this.getPrev() , this.next());
}
@Override
public DoubleLinkedElmt next() {
return this.next;
}
@Override
public void setData(DATA data) {
this.data = data;
}
@Override
public void setNext(DoubleLinkedElmt next) {
this.next = next;
}
@Override
public void setPrev(DoubleLinkedElmt prev) {
this.prev = prev;
}
};
result.setData(data);
return result;
}
/**
* Get previous {@link DoubleLinkedElmt}
* @return {@link DoubleLinkedElmt}
*/
public DoubleLinkedElmt getPrev();
/**
* Set previous {@link DoubleLinkedElmt}
* @param prev {@link DoubleLinkedElmt}
*/
public void setPrev(DoubleLinkedElmt prev);
}
/**
* Default {@link DoubleLinked}
* @param data type
*/
public class MyDoubleLinked implements DoubleLinked {
@Serial
private static final long serialVersionUID = 8162911921677856435L;
/**action count*/
private long actionCount = 0;
/**element factory*/
private final Function> elmtFactory;
/**head of the elements*/
private DoubleLinked.DoubleLinkedElmt head;
/**size*/
private int size;
/**tail of the elements*/
private DoubleLinked.DoubleLinkedElmt tail;
/**
* Build {@link MyDoubleLinked}
* @param elmtFactory {@link DoubleLinkedElmt} factory
*/
public MyDoubleLinked(Function> elmtFactory) {
this.elmtFactory = elmtFactory;
}
@Override
public void clear() {
do
this.remove(this.head);
while (this.size != 0);
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
DoubleLinked that;
if (obj instanceof DoubleLinked) {
that = (DoubleLinked) obj;
return this.size == that.size() && Objects.equals(this.head() , that.head()) && Objects.equals(this.tail() , that.tail());
} else return false;
}
@Override
public Function> getElmtFactory() {
return this.elmtFactory;
}
@Override
public int hashCode() {
return Objects.hash(this.head , this.size , this.tail);
}
@Override
public DoubleLinked.DoubleLinkedElmt head() {
return this.head;
}
@Override
public void insNext(DoubleLinked.DoubleLinkedElmt element , final DATA data) {
//Do not allow a NULL element unless the list is empty.
if (element == null && this.size() != 0) throw new LinkedOperationException("Do not allow a NULL element unless the list is empty.");
DoubleLinked.DoubleLinkedElmt new_element = this.getElmtFactory().apply(data);
if (this.size() == 0) {
//Handle insertion when the list is empty.
this.head = new_element;
this.head.setPrev(null);
this.head.setNext(null);
this.tail = new_element;
} else {
//Handle insertion when the list is not empty.
new_element.setNext(element.next());
new_element.setPrev(element);
if (element.next() == null) this.tail = new_element;
else element.next().setPrev(new_element);
element.setNext(new_element);
}
//Adjust the size of the list to account for the inserted element.
this.size++;
this.actionCount++;
}
@Override
public void insPrev(DoubleLinked.DoubleLinkedElmt element , final DATA data) {
//Do not allowed a NULL element unless the list is empty.
if (element == null && this.size() != 0) throw new LinkedOperationException("Do not allowed a NULL element unless the list is empty.");
DoubleLinked.DoubleLinkedElmt new_element = this.getElmtFactory().apply(data);
if (this.size() == 0) {
//Handle insertion when the list is empty.
this.head = new_element;
this.head.setPrev(null);
this.head.setNext(null);
this.tail = new_element;
} else {
//Handle insertion when the list is not empty.
new_element.setNext(element);
new_element.setPrev(element.getPrev());
if (element.getPrev() == null) this.head = new_element;
else element.getPrev().setNext(new_element);
element.setPrev(new_element);
}
//Adjust the size of list to accoutn for the element.
this.size++;
this.actionCount++;
}
@Override
public Iterator iterator() {
return new Iterator() {
private DoubleLinked.DoubleLinkedElmt index = MyDoubleLinked.this.head;
private final long myActioncount = MyDoubleLinked.this.actionCount;
@Override
public boolean hasNext() {
if (this.myActioncount != MyDoubleLinked.this.actionCount) throw new ConcurrentModificationException();
return this.index != null;
}
@Override
public DATA next() {
DoubleLinked.DoubleLinkedElmt result = this.index;
this.index = this.index.next();
return result.data();
}
};
}
@Override
public DATA remNext(DoubleLinkedElmt element) {
DoubleLinkedElmt old_element = this.getElmtFactory().apply(null);
DATA data = null;
if (this.size() == 0) throw new LinkedOperationException("Do not allow removal from an empty list.");
//Remove the element from the list.
if (element == null) {
//Handle removal from the head of the list.
data = this.head.data();
old_element = this.head;
this.head = this.head.next();
if (this.size() == 1) this.tail = null;
} else {
if (element.next() == null) return null;
data = element.next().data();
old_element = element.next();
element.setNext(element.next().next());
if (element.next() == null) this.tail = element;
}
old_element.free();
//Adjust the size of the list of account for the removed element.
this.size--;
this.actionCount++;
return data;
}
@Override
public DATA remove(DoubleLinked.DoubleLinkedElmt element) {
DATA data = null;
//Do not allow a NULL element or removal from an empty list.
if (element == null || this.size() == 0) throw new LinkedOperationException("Do not allow a NULL element or removal from an empty list.");
//Remove the element from the list.
data = element.data();
if (element.equals(this.head)) {
//Handle removal from the head of the list.
this.head = element.next();
if (this.head == null) this.tail = null;
else element.next().setPrev(null);
}
//Free the storage allocated by the abstract datatype.
element.free();
//Adjust the size of the list to account for the removed element.
this.size--;
this.actionCount++;
return data;
}
@Override
public int size() {
return this.size;
}
@Override
public DoubleLinked.DoubleLinkedElmt tail() {
return this.tail;
}
}
/**
* Get default {@link DoubleLinked}
* @return {@link DoubleLinked}
* @param data type
*/
public static DoubleLinked defaultDoubleLinked() {
return DoubleLinked.defaultDoubleLinked(DoubleLinkedElmt::defaultElmt);
}
/**
* Get default {@link DoubleLinked}
* @param elmtFactory {@link DoubleLinkedElmt} factory
* @return {@link DoubleLinked}
* @param data type
*/
public static DoubleLinked defaultDoubleLinked(Function> elmtFactory) {
return new MyDoubleLinked<>(elmtFactory);
}
/**
* Insert in the previous position of the {@link DoubleLinkedElmt}
* @param element {@link DoubleLinkedElmt}
* @param data the data
*/
public void insPrev(DoubleLinkedElmt element , final D data);
/**
* Remove the {@link DoubleLinkedElmt}
* @param element {@link DoubleLinkedElmt}
* @return the data which is omitted
*/
public D remove(DoubleLinkedElmt element);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy