文章目录
1.集合
数组:容器。 基本类型和引用类型;
长度固定。
集合:容器。存储引用类型;
变长。(自动的扩容).
集合里使用Iterator,Collection,List,Set,Map数据结构
数据结构如下
2.Collection集合
Collection:可以存储重复的数据,无顺序。
List:线性表。 可以存储重复的数据。有序。(线性排列)
2.1 Collection
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
//
System.out.println(c.isEmpty());//true
//添加 ,添加成功 true
c.add("aa");
c.add("bb");
c.add("cc");
System.out.println(c);//[aa, bb, cc]
// 1. 集合是空的 true
System.out.println(c.isEmpty());//false
// 2. 集合重元素的个数
System.out.println(c.size());//3
// 新的集合 :C1
Collection<String> c1 = new ArrayList<>();
c1.add("dd");
c1.add("ee");
c1.add("ff");
System.out.println(c1);//[dd, ee, ff]
// 3. 把参数集合中的所有元素 添加到当前集合c中,只要当前集合发生了改变返回true
c.addAll(c1);
System.out.println(c);//[aa, bb, cc, dd, ee, ff]
// 4. 把参数对象从当前集合中移除掉,只要当前集合发生了改变返回true
c.remove("cc");
System.out.println(c);//[aa, bb, dd, ee, ff]
// 5. 把 参数集合中的所有元素 从当前集合c中移除掉
c.removeAll(c1);
System.out.println(c);//[aa, bb]
//6. 把不在 参数集合中的所有元素 从当前集合中移除掉
c.retainAll(c1);//
System.out.println(c);// [dd, ee, ff]
//7. 参数对象 在当前集合中是否包含,存在 true
System.out.println(c.contains("ee"));// true
//8. 参数集合中的所有元素 在当前集合中是否 包含,包含true
System.out.println(c.containsAll(c1));// true
//9. 集合转数组
Object [] obj = c.toArray();
obj = c.toArray(new Object [0]);//[dd, ee, ff]
//保留类型
String [] strs = c.toArray(new String[0]);
Arrays.stream(obj).forEach(System.out::println);
// 10 . 清空集合
c.clear();
System.out.println(c.size());
System.out.println(c.isEmpty());
}
2.2 List
List:线性表。
数据结构:数据之间的关系,数据的组织形式。
线性表:
一个 由很多 相同特性的元素组成的 有序的序列。
一个元素 连接 下一个元素。
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("aa");// 0
list.add("bb");// 1
list.add("cc");// 2
// 1. add 把一个对象 添加到指定的索引处。
list.add(1, "hello");
System.out.println(list);//[aa, hello, bb, cc]
// 2. 获得参数索引位置的元素
System.out.println(list.get(1));// "hello"
// 3. 把指定的索引处的 元素 改为 第二个参数指定的元素。
list.set(1, "Tom");
System.out.println(list);// [aa, Tom, bb, cc]
//
list.add("cc");
list.add("cc");
System.out.println(list);// [aa, Tom, bb, cc, cc, cc]
// 4. 获得参数 对象 在集合中 第一次出现的位置索引
System.out.println(list.indexOf("cc"));// 3
// 5. 获得参数 对象 在集合中 最后一次出现的位置索引
System.out.println(list.lastIndexOf("cc"));//5
// 6. 子集 【起始位置,终止位置)
System.out.println(list.subList(1, 3));//[Tom, bb]
// 7. 排序
// null 没有指定Comparator,会按照自然排序Comparable
list.sort(null);
System.out.println(list);// [Tom, aa, bb, cc, cc, cc]
//自己定制顺序
list.sort((s1,s2)->{return s2.compareTo(s1);});
System.out.println(list);//[cc, cc, cc, bb, aa, Tom]
}
2.3 集合遍历
2.3.1 Iterator
Collection<String> c = new ArrayList<>();
c.add("aa");
c.add("bb");
c.add("cc");
System.out.println(c);
//-----------------------遍历数组元素----------------------------------
// 1. 增强循环 for
for(String s : c) {
System.out.println(s);
}
// 2. 集合对象的forEach方法
c.forEach(System.out::println);
// 3. Stream流的方法
c.stream().forEach(System.out::println);
// 4. Iterator
System.out.println("------------------------------");
// 获得了一个迭代器对象
Iterator<String> i = c.iterator();
System.out.println(i.next());// "aa"
System.out.println(i.next());// "bb"
i.remove();// 最近一次next访问的元素
System.out.println(c);
while(i.hasNext()) {//true,false
System.out.println(i.next());
}
// 5. forEachRemaining方法
Iterator<String> i1 = c.iterator();
i1.forEachRemaining(System.out::println);
迭代器的正序与逆序输出:
注意:迭代器想要实现逆序输出需先进行正序输出
ListIterator<String> i = c.ListIterator();
//正序
while(i.hasNext()) {//true,false
System.out.println(i.next());
}
//逆序
while(i.hasPrevious()) {//true,false
System.out.println(i.previous());
}
List:线性表。
数据结构:数据之间的关系,数据的组织形式。
线性表:
一个 由很多 相同特性的元素组成的 有序的序列。
一个元素 连接 下一个元素。
2.4 底层的技术:
1.数组:
ArrayList : 线程非安全。性能好。
扩容:1.5倍。
Vector: 线程安全的。性能低。
扩容: 2倍。
2.链表
一些 非连续的结点 组成的 存储结构。
分类:
单向链表 :
链域只有一个的。
单向非循环 和 单向循环:
双向链表:
双向非循环 和 双向循环:
ArrayList 和 LinkedList区别:
ArrayList : 遍历或随机访问,效率高;
LinkedList:遍历或随机访问,效率低;
ArrayList:插入元素 或删除元素 效率低
ArrayList扩容原码:
new ArrayList();
public ArrayList() {
private static final Object[] EMPTY_ELEMENTDATA = {}; 长度为0 的数组
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
list.add(“aa”);的源码:
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 采取的是 初始容量10
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0) // 存储的个数超过了 初始容量10,继续扩容
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;// 旧的容量= 数组长度
int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容:旧的容量 = 旧的容量 + 旧的容量/2;
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//数组复制
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE; //存储的个数超过了 MAX_ARRAY_SIZE:Integer.MAX_VALUE-8 采取 Integer.MAX_VALUE
}
链表的结点 原码:
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;
}
}
添加add()原码:
源码如下:
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++;
}
4.编写:List类 存储Dog信息
- 练习:List
- 存储Dog信息
import java.util.ArrayList;
import java.util.List;
class Dog implements Comparable<Dog>{
private String name;
private String type;
private int age;
public Dog(String name, String type, int age) {
this.name = name;
this.type = type;
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Dog [name=" + name + ", type=" + type + ", age=" + age + "]";
}
@Override
public int compareTo(Dog o) {
return this.age - o.age;
}
}
public class TestList_exam {
public static void main(String[] args) {
List<Dog> dogs = new ArrayList<>();
Dog wangwang = new Dog("旺旺", "松狮", 2);
Dog wangcai = new Dog("旺财", "金毛", 1);
Dog meimei = new Dog("美美", "吉娃娃", 3);
dogs.add(wangwang);
dogs.add(wangcai);
dogs.add(meimei);
//遍历输出Dogs信息
for(Dog dog : dogs) {
System.out.println(dog);
}
//Comparable升序
dogs.sort(null);
System.out.println("---------升序------------");
for(Dog dog : dogs) {
System.out.println(dog);
}
//Comparator降序
dogs.sort((dog1,dog2)->{return dog2.getAge() - dog1.getAge();});
System.out.println("---------降序------------");
for(Dog dog : dogs) {
System.out.println(dog);
}
//删除美美
dogs.remove(meimei);
System.out.println(dogs.size());
}
}
5.注意:
x>>1相当于
x乘以1.5倍(向右移一位)
2.
扩容每次阔1.5倍,要是扩容了还不够,直接扩为所需的大小,对于Integer.MAX.Value来说,,最多扩容到int的上限
3.
不断的扩容会降低系统的运算速度
4.链表
节点存数据
值域存数值,链域存位置