Java集合


List

    1.ArrayList——默认从10开始自增插入

其中内部类的用处!

内部类Itr实现Iterarot接口;

ListIterator 继承 Itr 实现 ListIterator接口

SubList extends AbstractList<E> implements RandomAccess

private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;

ArrayList.SubList

//内部类访问外部类属性、方法
this.modCount = ArrayList.this.modCount;
ArrayList.this.elementData(offset + index);


--注意:Arrays 的内部类 ArrayList 继承的是 AbstractList   [没有add()方法]  || 同理:Collections工具类,直接定义不可修改的ArrayList,所有更改结构:add()\remove()方法内部直接抛异常。
private static class ArrayList<E> extends AbstractList
只实现了:
1.size()
2.toArray()
3.get(int)
4.set(int,E)
5.indexOf(Object)   contains(Object)


判断是否存在当前集合内

private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];

} finally {
//主要是防止 中间抛出异常
//以及将elementData[]数组补全操作
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
Some VMs reserve some header words in an array.

    2.  LinkedList

Node 的定义://抽象部分,next、prev 前后链接

private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;

Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

操作指针的严密逻辑:更新first、last; 注意 null 节点的存在

private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;

size++;
modCount++;
}

同理,linkLast(E e)

final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;

//在Node前插入
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;

size++;
modCount++;
}

同理:在节点之后插入,

释放第一个节点,最后一个节点、任意一个节点

if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}

if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}

x.item = null;


//封装的思想

public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
public void addFirst(E e) {
linkFirst(e);
}
//指针遍历
public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}

//逐渐能够操作数组等容器类
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);
//数组是我的强项——多维拼接,所以大数据方面
Object[] a = c.toArray();//还是还原回数组
int numNew = a.length;
if (numNew == 0)
return false;

Node<E> pred, succ;
if (index == size) {
succ = null;
pred = last;
} else {
succ = node(index);
pred = succ.prev;
}

for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
Node<E> newNode = new Node<>(pred, e, null);
if (pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;
}

    //细节问题;范围边界处理
if (succ == null) {
last = pred;
} else {
pred.next = succ;
succ.prev = pred;
}


size += numNew;
modCount++;
return true;
}
LinkedList 实现了栈的功能
+push(in:E e)
{//方法体:通过使用addFirst(e)
}

+pop()
{//通过使用removeFirst();
}

同理:也可以通过操作队尾实现。
//addLast(e) && removeLast();

指针对比ArrayList数组
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();

lastReturned = next;
next = next.next;

nextIndex++;
return lastReturned.item;
}
//成员属性:nextIndex 游标指示当前位置
public boolean hasPrevious() {
return nextIndex > 0;
}
public boolean hasNext() {
return nextIndex < size;
}


//ArrayList
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];

}

//ListIterator 部分
public boolean hasPrevious() {
return cursor != 0;
}
public boolean hasNext() {
return cursor != size;
}

Lisitr



共性与区别

迭代器实现

区别于:ArrayList的故障快速迭代器

fail-fast iterators:int modCount;

map

--TreeMap:有顺序: Map.Entry 接口对象!

——comparator  ,构造TreeMap 传参,匿名构造

——comparable ,value对象实现  Comparable 接口



//常用操作:
TreeMap treeMap = new TreeMap();
treeMap.put("1","张三,20");
treeMap.put("3","张三,20");
treeMap.put("6","张三,20");
treeMap.put("4","张三,20");
treeMap.put("5","张三,20");
treeMap.put("2","李四,20");
treeMap.forEach((key, value) -> {
System.out.println(key+":"+value);
});
for (Object entry:treeMap.entrySet()){
System.out.println(entry.toString());
}
TreeMap<String,String> treeMap1 = new TreeMap();
treeMap1.put("1","张三,20");
treeMap1.put("2","李四,20");
for (Map.Entry entry:treeMap1.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue());
}


--HashMap

System.out.println("EntrySet 遍历:");
for (HashMap.Entry entry:map.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue());
}
System.out.println("keySet 遍历:");
for (String s:map.keySet()){
System.out.println(s+":"+map.get(s));
}


获取hash值:(n - 1) & hash

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}


equals的对象必须有相同的哈希值:因为 HashMap类做了这方面的相关操作:


final Node<K,V> removeNode(int hash, Object key, Object value,
                           boolean matchValue, boolean movable) {

//都存在这部分相同的代码:
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
node = p;

}


public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}

---========----

所以:如果key对象是一个自定义对象的时候,必须保障: hashCode() 方法 与 equals(Object obj) 方法 为 业务上的同一个对象!!

@Override
public int hashCode() {
return index;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Xuehao){
Xuehao temp = (Xuehao) obj;
if (temp.index == this.index){
return true;
}

}
return false;
}







LinkedHashMap

//LinkedHashMap 在 HashMap的基础上增加了如下内容:
//增强:保持元素的插入顺序
//head:第一个元素的引用,指向按插入顺序
//tail:最后一个元素的引用,指向按插入顺序

LinkedHashMap 支持LRU算法,
//LinkedHashMap 具有HashMap 的所有功能 +可保持插入顺序(遍历)
//HashMap + 双向链表
//双向链表:head、tail;after、before

//LinkedHashMap是有序的   boolean  accessOrder
//1. 插入顺序:每次插入元素,将元素放到双向链表的末尾
//2. 访问顺序:每次插入、获取元素,将该元素放到双向链表的末尾


Set

//数组或者实现了 Iterable接口地类可以用于 for each 语法

/**Set 内部使用的是对应的Map来实现的,Map的key值即是set值,
* key值对应的值即 static new Object()
*Map中的Key值不可以重复,可以是null

HashSet(代填坑):HashSet无序的,同样的索引值取出来的值可能不一样

HashSet<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");
set.add("D");
set.add("E");
set.add("F");
/*for (int i = 0; i < set.size(); i++) {
//HashSet无序的,同样的索引值取出来的值可能不一样

}*/

Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}


LinkedHashSet(代填坑):实现插入有序

LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add("4");
linkedHashSet.add("5");
linkedHashSet.add("4");
linkedHashSet.add("5");
linkedHashSet.add("1");
linkedHashSet.add("2");
linkedHashSet.add("3");
linkedHashSet.add("1");
linkedHashSet.add("2");
linkedHashSet.add("3");

/*Iterator iterator = linkedHashSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}*/
System.out.println("2".compareTo("3"));
//linkedHashSet.remove("2");
System.out.println(linkedHashSet);
Collection<String> collection = new HashSet<>();
collection.add("1");
collection.add("2");
linkedHashSet.removeAll(collection);
System.out.println(linkedHashSet);



TreeSet有序,指的是元素按照一定规则来排序,Comparator接口

/**TreeSet 有序,指它的内容--->TreeMap的key值
*TreeSet的值不能是null?
* 1. 如果构造TreeSet时,指定了 Comparator,则可以存放null
* 2. 如果未指定Comparator,add添加元素时需要调用元素对象的
* compareTo()---Comparable接口,因此不可存放null
*/

TreeSet<String> treeSet = new TreeSet<>();
treeSet.add("1");
treeSet.add("4");
treeSet.add("2");
treeSet.add("3");
Iterator iterator = treeSet.iterator();
System.out.println(treeSet);
while (iterator.hasNext()){
System.out.println(iterator.next());
}

treeSet.remove("2");
//treeSet.add(null);
System.out.println(treeSet);


compareTo() 方法重写

String类:

public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;

int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}




Queue

*Queue
* 定义:一种在队尾进行插入,队头进行删除
* 两端队列:同时在队尾、队头进行插入、删除操作
* 特点:
* 只能对队头或队尾元素进行操作,而不能对队列中间的元素进行操作
* 先进先出
* 后进后出

*接口:Queue、Deque
*实现类:
* 1. LinkedList 具有队列、两端队列功能,内部使用链表实现
* 2. ArrayDeque 具有队列、两端队列功能,内部使用循环数组实现
* 3. PriorityQueue 优先级队列,内部实现结构(栈)可以快速把所有元素中最小的元素单独放出来

* 最典型的应用场景:任务调度
* 应用场景:任务调度、LRU

LinkedList---实现Deque接口



Queue接口

add(E) && offer(E)

---内容限制,有限使用offer(E)

element() && peek() [retrive the head]

---队列为空,element() 抛异常;peek() 返回null

remove() && poll() [retrive the head and remove]

---队列为空,element() 抛异常;peek() 返回null


Deque接口(Douoble ended queue):insert, remove, and examine the element

每种方法两种表现形式:one throws an exception if the operation fails,
the other returns a special value (either {@code null} or {@code false}, depending on the operation).

参考JDK:

<table BORDER CELLPADDING=3 CELLSPACING=1>
* <caption>Summary of Deque methods</caption>
* <tr>
* <td></td>
* <td ALIGN=CENTER COLSPAN = 2> <b>First Element (Head)</b></td>
* <td ALIGN=CENTER COLSPAN = 2> <b>Last Element (Tail)</b></td>
* </tr>
* <tr>
* <td></td>
* <td ALIGN=CENTER><em>Throws exception</em></td>
* <td ALIGN=CENTER><em>Special value</em></td>
* <td ALIGN=CENTER><em>Throws exception</em></td>
* <td ALIGN=CENTER><em>Special value</em></td>
* </tr>
* <tr>
* <td><b>Insert</b></td>
* <td>{@link Deque#addFirst addFirst(e)}</td>
* <td>{@link Deque#offerFirst offerFirst(e)}</td>
* <td>{@link Deque#addLast addLast(e)}</td>
* <td>{@link Deque#offerLast offerLast(e)}</td>
* </tr>
* <tr>
* <td><b>Remove</b></td>
* <td>{@link Deque#removeFirst removeFirst()}</td>
* <td>{@link Deque#pollFirst pollFirst()}</td>
* <td>{@link Deque#removeLast removeLast()}</td>
* <td>{@link Deque#pollLast pollLast()}</td>
* </tr>
* <tr>
* <td><b>Examine</b></td>
* <td>{@link Deque#getFirst getFirst()}</td>
* <td>{@link Deque#peekFirst peekFirst()}</td>
* <td>{@link Deque#getLast getLast()}</td>
* <td>{@link Deque#peekLast peekLast()}</td>
* </tr>
* </table>


自定义简单实现应用:ArraySequence—& —内部类

//接口定义
public interface IndexPrint {
public boolean end();
public Object current();
public void next();
}
//封装正向访问、逆向访问类
public class ArraySequence implements IndexPrint{
private int count = 0;
private Object[] data;

public ArraySequence(int size){
this.data = new Object[size];
}

public Verse pro(){
return new Verse();
}
public Reverse pro1(){
return new Reverse();
}

public void add(Object object){
if(count<data.length){
data[count++] = object;
//reverseIndex++;
}
}
@Override
public boolean end(){
return count==data.length;
}

@Override
public Object current() {
return null;
}

@Override
public void next() {

}

class Verse implements IndexPrint{
private int index = 0;
@Override
public boolean end() {
return index>=count;
}

@Override
public Object current() {
if(index<count){
return data[index];
}
return null;
}

@Override
public void next() {
index++;
}
}
class Reverse implements IndexPrint{
private int reverseIndex=count;
@Override
public boolean end() {
return (reverseIndex-1) <0;
}

@Override
public Object current() {
if((reverseIndex-1)<count){
return data[reverseIndex-1];
}
return null;
}

@Override
public void next() {
reverseIndex--;
}
}

public void print(){
System.out.println(Arrays.toString(data));
}
}

优先级队列应用

static class Task implements Comparable{
private int priority;
private String name;
public Task(int priority,String name){
this.priority = priority;
this.name = name;
}

public int getPriority() {
return priority;
}

public void setPriority(int priority) {
this.priority = priority;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public int compareTo(Object o) {
if(o instanceof Task){
if(this.priority<((Task) o).priority){
return -1;
}
if(this.priority>((Task) o).priority){
return 1;
}

}
return 0;
}

@Override
public String toString() {
return this.name+":"+this.priority;
}
}

static void taskManage(){
PriorityQueue<Task> priorityQueue = new PriorityQueue<>(new Comparator<Task>() {
@Override
public int compare(Task o1, Task o2) {
if(o1.getPriority()<o2.getPriority()){
return -1;
}
if(o1.getPriority()>o2.getPriority()){
return 1;
}
return 0;
}
});
//priorityQueue.add(new())
int i=0;
while ((i)<10){
int priority = new Random().nextInt(10);
priorityQueue.add(new Task(priority,"任务"+i));
i++;
}
System.out.println(priorityQueue);
while (!priorityQueue.isEmpty()){
System.out.println(priorityQueue.remove());
}
}







从Java集合类中看到内部类的重要性!

老师说的不重要性:或许仅限于,Java网页开发??



Java集合类学习泛型应用

   1:LinkedList 内部类 Node定义
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;

Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

    2:LinkedList插入元素:安全性意识

不改变元素的值:final修饰,安全性!

void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}


泛型方法

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}



快速查询第index处的node节点

Node<E> node(int index) {
// assert isElementIndex(index);

if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
从输出结果:也能看出Java面向对象的思想!
Integer[] numb = new Integer[2];
System.out.println(numb);//输出数组名@hash地址
Integer[] numb1 = {};
System.out.println(numb1);
numb1 = null;
System.out.println(numb1);//null

最终比拼的是:

业务能力

跟实际业务的关联关系捋清楚

人际成单招标能力



//StringBuffer \ StringBuilder 操作字符串

public String toString() {
//return name+":"+age;
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append("{");
sb.append(name);
sb.append(",");
sb.append(age);
sb.append("}");
return sb.toString();
}

//转义符的应用

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}


注解应用:
@SuppressWarnings("unchecked") E e = (E) o;

多变量赋值:

int a,b;

a = b = true?1:3;


区分

StringBuffer  &&  StringBuilder

---默认长度 16

posted @ 2020-03-17 09:29  小海_macro  阅读(169)  评论(0编辑  收藏  举报