System.arrayCopy:数组拷贝且指定源数组、目标数组等等
Arrays.copyOf:整个数组拷贝到新的数组
1.迭代器的两个作用:
(1)为了统一接口的遍历方式:
顺序表还是链表,遍历方式是一致的,用户不需要关心内部实现(封装性)
(2)可以删除元素
2.懒加载:
好处:节省空间,用的时候在申请
坏处:第一次用的时候耗费时间长
3.实现一个顺序表与双向链表
//List接口
public interface List {
// 尾插
boolean add(int element);
// 把数据插入到 index 下标处
boolean add(int index, int element);
int get(int index);
int set(int index, int val);
// 删除指定位置的数据
int remove(int index);
int size();
boolean isEmpty();
}
//实现顺序表
public class ArrayList implements List {
int[] array = null;
int size;
public void ensureCapacity() {
if (array != null && size < array.length) {
return;
}
int capacity;
if (array == null) {
capacity = 10;
} else {
capacity = 2 * array.length;
}
if (array == null) {
array = new int[capacity];
}
array = Arrays.copyOf(array, capacity);
}
// public void ensureCapacity() {
// if(array!=null&&size<array.length){
// return;
// }
// int oldCapacity = array.length;
// int newCapacity = 2 * oldCapacity;
// int[] newArray = new int[newCapacity];
// for(int i = 0;i<size;i++){
// newArray[i]=array[i];
// }
// array=newArray;
// }
@Override
public boolean add(int element) {
return add(size, element);
}
@Override
public boolean add(int index, int element) {
if (index < 0 || index > size) {
System.out.println("下标不合法");
return false;
}
ensureCapacity();
System.arraycopy(array, index, array, index + 1, size - index);
array[index] = element;
size++;
return true;
}
@Override
public int get(int index) {
if (index < 0 || index >= size) {
return -1;
}
return array[index];
}
@Override
public int set(int index, int val) {
if (index < 0 || index >= size) {
return -1;
}
int oldValue = array[index];
array[index] = val;
return oldValue;
}
@Override
public int remove(int index) {
if (index < 0 || index >= size) {
return -1;
}
int value = array[index];
System.arraycopy(array, index + 1, array, index, size - index - 1);
size--;
return value;
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public String toString(){
return Arrays.toString(Arrays.copyOf(array,size));
}
}
//实现双向链表
public class LinkedList implements List{
private class Node{
private int value;
private Node next;
private Node pre;
private Node(int value) {
this.value = value;
}
private Node(int value, Node next, Node pre) {
this.value = value;
this.next = next;
this.pre = pre;
}
}
private Node head = null;
private Node last = null;
private int size = 0;
@Override
public boolean add(int element) {
return add(size,element);
}
@Override
public boolean add(int index, int element) {
if(index<0 && index>size){
System.out.println("插入位置不合法");
return false;
}
if(index == 0){
Node newNode = new Node(element,head,null);
if (newNode.next != null) {
newNode.next.pre = newNode;
}else {
last = newNode;
}
head = newNode;
size++;
return true;
}
if(index == size){
Node newNode = new Node(element,null,last);
if(newNode.pre != null){
newNode.pre.next = newNode;
}else {
head = newNode;
}
last = newNode;
size++;
return true;
}
Node cur = getNode(index);
Node newNode = new Node(element,cur.pre,cur);
cur.pre.next = newNode;
cur.pre = newNode;
size++;
return true;
}
private Node getNode(int index) {
int middle = size/2;
if(index<middle){
Node cur = head;
for(int i = 0;i<index;i++){
cur = cur.next;
}
return cur;
}else {
Node cur = last;
for(int i = 0;i<size-index-1;i++){
cur = cur.pre;
}
return cur;
}
}
@Override
public int get(int index) {
if(index<0&&index>=size){
return -1;
}
return getNode(index).value;
}
@Override
public int set(int index, int val) {
if(index<0&&index>=size){
return -1;
}
int oldValue = getNode(index).value;
getNode(index).value = val;
return oldValue;
}
@Override
public int remove(int index) {
if(index<0&&index>=size){
return -1;
}
Node cur = getNode(index);
if(cur.pre!= null){
cur.pre.next = cur.next;
}else {
head = head.next;
}
if(cur.next!=null){
cur.next.pre = cur.pre;
}else {
last = last.pre;
}
size--;
return cur.value;
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public String toString() {
String result = "[";
for(Node node = head;node!=null;node = node.next){
result += (node.value+" ");
}
result +="]";
return result;
}
}
//测试
public class Main {
public static void main(String[] args) {
List arrayList = new ArrayList();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
arrayList.add(4);
String result = arrayList.toString();
System.out.println(result);
System.out.println(arrayList.size());
System.out.println(arrayList.isEmpty());
int a =arrayList.get(0);
System.out.println(a);
int b = arrayList.set(0,7);
String result1 = arrayList.toString();
System.out.println(result1);
int c = arrayList.remove(1);
System.out.println(c);
String result3 = arrayList.toString();
System.out.println(result3);
System.out.println("----------------------------------------");
List linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
linkedList.add(4);
String result2 = linkedList.toString();
System.out.println(result2);
System.out.println(linkedList.size());
System.out.println(linkedList.isEmpty());
int e = linkedList.get(0);
System.out.println(e);
int f = linkedList.set(0,7);
String result4 = linkedList.toString();
System.out.println(result4);
int g = linkedList.remove(1);
System.out.println(g);
String result5 = linkedList.toString();
System.out.println(result5);
}
}
//运行结果
[1, 2, 3, 4]
4
false
1
[7, 2, 3, 4]
2
[7, 3, 4]
----------------------------------------
[1 2 3 4 ]
4
false
1
[7 2 3 4 ]
2
[7 3 4 ]
4.链表的练习
问题:传入一个值x,小于x的结点值放在x的前面,大于x的结点值放在x的后面
public static Node partition(Node head,int x){
Node cur = head;
Node small = null;
Node smallLast = null;
Node big = null;
Node bigLast = null;
for(;cur!=null;cur = cur.next){
if(cur.val<x){
if(small == null){
small = cur;
}else {
smallLast.next = cur;
}
smallLast = cur;
}else {
if(big == null){
big = cur;
}else {
bigLast.next = cur;
}
bigLast = cur;
}
}
if(smallLast == null){
return big;
}else{
smallLast.next = big;
}
if(bigLast == null){
return small;
}else{
bigLast.next = null;
}
return small;
}