一、集合
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++;
}
?
|