一、集合
1.1 概述
java集合是使能够储存和操纵元素不固定的一组数据,所以java集合类都位于java。util包中
注意 :如果集合中存放基本类型,一定要将其“装箱”成对应的“基本类型包装类”
1、2 继承体系
由以上两图我们可以看出Java集合类有清晰的继承关系,有很多子接口和实现类。但是,并不是所有子接口或实现类都是最常用的。
下面我们列举出最常用的几个子接口和实现类:
Collection ——> List ——> ArrayList类
Collection ——> List ——> LinkedList类
Collection ——> Set ——> HashSet类
Collection ——> Set ——> SortedSet接口 ——> TreeSet类
Map ——> HashMap类
Map ——> SortedMap ——> TreeMap类
二、Collection
2、1 方法
2.2 注意
* boolean contains(Object o):判断是否包含某个元素
* boolean remove(Object o):删除指定元素
* 这两个方法,底层都会调用equals方法进行比较
* 比如 c.contains("abc");会用abc调用equals方法和集合中所有的元素
* 所以 如果储存的是自定义的类型,比如User等
* 那么想要使用contains和remove就需要覆写equals方法
public class Collection_03 {
public static void main(String[] args) {
Collection c = new ArrayList();//数组列表
c.add(1);
c.add(new Integer(1));
System.out.println(c.size());
Integer i1 = new Integer(1);
Manager m1 =new Manager(1,"张三");
Manager m2 = new Manager(1,"张三");
c.add(m1);
System.out.println(c.contains(m1));
System.out.println(c.contains(m2));
}
}
class Manager{
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Manager) {
Manager m = (Manager) obj;
if (no == m.no && name.equals(m.name)) {
return true;
}
}
return false;
}
private int no;
private String name;
public Manager(int no, String name) {
super();
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
三、Lterator
1、Collection接口的iterator()和toArray()方法都用于获得集合中所有元素,前者返回一个
Iterator对象,后者返回一个包含集合中所有元素的数组
2、Itera接口隐藏底层集合中的数据结构,提供各种类型集合的统一接口
for与iterator对比
Iterator的好处在于可以使用同样的方法去遍历集合,而不用考虑集合类的内部实现
使用Iterator来遍历集合中的元素,如果不使用list转而使用set来组织数据,则遍历代码不用做任何修改
使用for来遍历,那所以遍历集合的算法都得做相应调整,因为liat有序,set无序,结构不同
他们的相应算法都不同
for循环需要下标
2.2 方法
2.3 使用
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//迭代器:可以屏蔽底层数据存储的差异性
public class Collection_02 {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("asd");
c.add("123");
c.add("avc");
c.add("xxx");
c.add(false);
//生成迭代器
Iterator it =c.iterator();
//迭代器一旦创建,集合中元素不能删除和添加
//否则就要需要重新生成迭代器
while (it.hasNext()) {
Object object = it.next();
System.out.println(object);
// 如果在使用迭代器的过程中,需要进行删除,必须使用迭代器的remove方法
}
// 迭代器遍历完之后,想再次遍历 只能重新生成
it = c.iterator();
while (it.hasNext()) {
Object object = it.next();
System.out.println(object);
}
}
}
四、List
4.1 概述
/4.*List:有序可重复
* 存入顺序和取出顺序是一致
* ArrayList:底层是数组,查询和更改效率极高,添加和删除效率较低
* LinkedList :底层是双向链表,查询效率较低,添加删除效率较高
* Vector :已过时,底层是数组,ArrayList是Vector的升级版
* Vector默认容量是10,扩大容量是2倍,线程安全,效率较低
* ArrayList默认容量是10,扩大容量是1.5倍,非线程安全,效率较高
*/
4.2 ArrayList
public class Collection_04 {
public static void main(String[] args) {
//底层是Object[]数组,也就意味着只能保存引用类型
//但是由于基本类型会自动装箱为包装类型,所以导致Object[]数组 什么也能放
ArrayList list = new ArrayList();
//add(E e):将元素添加到列表的尾部
list.add(11);
//add(int index,E e):将元素添加到列表的指定位置
list.add(0,22);
//ArrayList覆写了toString方法,所以打印结果不是内存位置,
//而是里面是数据[22,11]
System.out.println(list);
//set(int index,E element):替换指定位置上的元素
list.set(1, 33);
System.out.println(list);
//get(int index):根据索引获取对应元素
System.out.println(list.get(1));
//remove(int index):根据索引删除元素
list.remove(1);
System.out.println(list);
//remove(Object obj):根据指定元素删除
//list.remove(22);这样删除的是(22是下标)
list.remove(new Integer(22));
System.out.println(list);
//遍历
// list.add(1);
//list.add(2);
//list.add(3);
//list.add(4);
//迭代器
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//forEach
for (Object object : list) {
System.out.println(it.next());
}
//for
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
4.3 LinkedList
4.3.1 概述
/*LinkedList :底层是双向链表
* 链表的节点,有三个部分构成:1、添加的元素2、下一个节点的引用,3、上一个节点的引用
* 链表数据结构,在内存中储存也不是连续的,所以没有固定下标
* 因为内存空间不是连续的,只能找到下一个节点,因此添加和删除就变得容易了
*
*/
4.3.2 基本使用
public class Collection_6 {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
//尾部添加 成功返回true
linkedList.add(1);
//头部添加
linkedList.push(2);
//尾部
linkedList.addLast(3);
//首部 成功返回true
linkedList.addFirst(4);
// 首部
linkedList.offerFirst(5);
// 尾部
linkedList.offerLast(6);
System.out.println(linkedList);
// 本质调用 的都是 linkLast 和 linkFirst,所以他们没有什么区别,主要是解决命名习惯问题
// 获取最后一个
System.out.println(linkedList.getLast());
// 获取第一个
System.out.println(linkedList.getFirst());
// 根据下标获取,只不过这个下标决定的是循环的次数,模拟出来下标获取数据而已
// 和数组的下标是两回事,因为链表是没有下标的
System.out.println(linkedList.get(3));
// 更改,设置对应下标的数据
linkedList.set(1, 2);
System.out.println(linkedList);
// 根据索引删除
linkedList.remove(1);
System.out.println(linkedList);
// 删除指定元素
linkedList.remove(new Integer(2));
System.out.println(linkedList);
// 获取第一个元素,并把它删除
linkedList.poll();
System.out.println(linkedList);
// 获取第一个元素,并把它删除
linkedList.pop();
System.out.println(linkedList);
}
}
4.3.3 底层实现
void linkLast(E e){
final Node<E> i = laxt;
final Node<E>newNode = new Node <>(i,e,null);
last = newNode;
if(i==null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}