------- android培训、java培训、期待与您交流! ----------
1:集合
(1)java是一种面向对象语言,如果我们要针对多个对象进行操作,就必须对多个对象进行存储。
而对多个元素进行存储,前面我们学习过数组,数组的弊端,长度固定。这样,数组将不能
满足变化的要求。所以,java就提供了集合供我们使用。
(2)集合的特点:
A:长度可以发生改变
B:只能存储对象
C:可以存储多种类型对象(一般存储的还是同一种)
(3)集合和数组的区别
A:长度问题:数组固定;集合可变。
B:存储元素问题:数组可以是基本类型,也可以是引用类型;集合只能是引用类型。
C:是否同一类型:数组元素类型一致;集合元素类型可以不一致。
(4)集合体系的由来
集合是存储多个元素的容器,但是,由于数据结构不同,java就提供了多种集合类。
而这多种集合类有共性的功能,所以,通过不断的向上抽取,最终形成了集合体系
结构。
数据结构:简单说就是数据存储的方式。
集合体系:
Collection(单列)
List(有序,可重复)
|--ArrayList底层数据结构是数组,查询快,增删慢。线程不安全,效率高。
|--Vector底层数据结构是数组,查询快,增删慢。线程安全,效率低。
|--LinkedList底层数据结构是链表,查询慢,增删快。线程不安全,效率高。
Set(无序,唯一)
|--HashSet底层数据结构是哈希表。线程不安全,效率高。
|--TreeSet底层数据结构是二叉树。线程不安全,效率高。
Map(双列 底层结构是针对键有效,跟值无关)
|--HashMap:底层数据结构是哈希表。线程不安全,效率高。允许null键和值。
|--Hashtable:底层数据结构是哈希表。线程安全,效率低。不允许null键和值。
|--TreeMap:底层数据结构是二叉树。线程不安全,效率高。
注:(1)HashSet、HashMap、Hashtable是如何保证元素的唯一性?
它要重写两个方法:hashCode()和equals()。
首先判断hashCode()值是否相同?
相同:继续走equals(),看返回值
如果true:就不添加到集合。
如果false:就添加到集合。
不同:就添加到集合。
代码体现:
public int hashCode() {
return this.name.hashCode() + this.age*13;//最大保证哈希值唯一
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Student)) {
return false;
}
Student s = (Student) obj;
return this.name.equals(s.name) && this.age == s.age;
}
(2)TreeSet、TreeMap是通过比较方法的返回时是否是0来保证元素的唯一性。
通过以下两种方法对元素排序。
1,自然排序(元素具备比较性),实现Comparable接口。TreeSet无惨构造,要求对象所属的类实现Comparable接口。
代码体现:
@Override
public int compareTo(Student s) {
// 需求是比较年龄
int num = this.age - s.age;
// 由于对象有多个成员变量,不能根据其中的某一个决定其他的。
// 当某一个相同的时候,还需要判断其他的是不是也是相同的。
int num2 = (num == 0) ? (this.name.compareTo(s.name)) : num;
return num2;
}
2,比较器排序(容器自身具备比较性),实现Comparator接口。TreeSet带参构造,要求构造方法接受一个实现类。
代码体现<1>自定义一个类继承Comparator:
public class MyComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
// 按年龄排序,从小到大
int num = s1.getAge() - s2.getAge();
// 次要条件
int num2 = (num == 0) ? (s1.getName().compareTo(s2.getName())) : num;
return num2;
}
}
代码体现<2>采用匿名内部类:
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 按年龄排序,从小到大
int num = s1.getAge() - s2.getAge();
// 次要条件
int num2 = (num == 0) ? (s1.getName().compareTo(s2.getName())) : num;
return num2;
}
});
2:Collection的功能
A:添加功能
boolean add(Object obj):向集合中添加元素
boolean addAll(Collection c):将一个集合中的元素添加到另一个集合中
B:删除功能
void clear():清除集合中的所有元素
boolean remove(Object obj):清除集合中指定的元素
boolean removeAll(Collection c):
C:判断功能
boolean isEmpty():判断集合石否为空
boolean contains(Object obj):判断集合是否包含指定的元素
boolean containsAll(Collection c):
D:遍历功能
Iterator iterator():迭代器
E:长度功能
int size():返回元素的个数
3:迭代器Iterator:所有Collection集合共性的取出方式,用来获取集合中的每一个元素。
A:成员方法
Object next():获取元素,并自动移动到下一个位置等待获取。
boolean hasNext():判断迭代器中是否还有元素。
B:迭代器原理
由于多种集合的数据结构不同,所以存储方式不同,所以,取出方式也不同。
这个时候,我们就把判断和获取功能定义在了一个接口中,将来,遍历哪种
集合的时候,只要该集合内部实现这个接口即可。
C:迭代器源码
public interface Iterator
{
public abstract boolean hasNext();
public abstract Object next();
}
public interface Collection
{
public abstract Iterator iterator();
}
public interface List extends Collection
{
...
}
public class ArrayList implements List
{
public Iterator iterator()
{
return new Itr();
}
private class Itr implements Iterator
{
public boolean hasNext(){...}
public Object next(){...}
}
}
4:应用。(添加功能,判断功能,删除功能,获取功能,长度功能)
Collection
A:添加功能(掌握)
boolean add(Object obj):向集合中添加元素
boolean addAll(Collection c):将一个集合中的元素添加到另一个集合中
B:删除功能(掌握)
void clear():清除集合中的所有元素
boolean remove(Object obj):清除集合中指定的元素
boolean removeAll(Collection c):
C:判断功能(掌握)
boolean isEmpty():判断集合石否为空
boolean contains(Object obj):判断集合是否包含指定的元素
boolean containsAll(Collection c):
D:遍历功能(掌握)
Iterator iterator():迭代器
E:长度功能(掌握)
int size():返回元素的个数
|--List的特有功能
A:添加功能
void add(int index,Object obj):
B:删除功能
Object remove(int index):
C:修改功能
Object set(int index,Object obj):
D:获取功能
Object get(int index):
int indexOf(Object obj):
ListIterator listIterator():
(2)ListIterator迭代器
A:是Iterator的子接口。
B:有自己的特有功能,可以逆向遍历数据,但是需要先正向遍历。一般不用。
(3)注意问题:并发修改异常ConcurrentModificationException
A:并发修改异常的产生原因
用迭代器遍历集合时,用集合去操作集合。
B:解决方案:
a:使用集合操作。
b:使用列表迭代器操作。
|--Set没有自己特有的方法,直接继承Collection
Map接口功能(Map集合中的具体实现类的数据结构,是针对键有效。)
A:增加功能
V put(K key,V value):当key在集合中不存在时,添加元素;当key在集合存在时候,替换元素。
B:删除功能
void clear():清除所有键值对数据。
V remove(Object key):根据指定的键删除键值对。
C:判断功能
boolean containsKey(Object key):判断指定的键是否在集合中存在
boolean containsValue(Object vlaue):判断指定的值是否在集合中存在
boolean isEmpty():判断集合是否为空
D:获取功能
Set<Map.Entry<K,V>> entrySet():键值对对象的集合。
Object get(Object key):根据键获取值
Set<K> keySet():所有键的集合
Collection<V> values():所有值的集合
E:长度功能
int size()
5:遍历方式
List:迭代器、增强for(开发中看到,JDK5以后用)、普通for。
如果仅仅为了遍历,用任意一种即可。一般选择前两种的任意一种。
如果要做修改,或者删除指定位置的元素,或者在指定位置添加元素。用普通for。
Set:迭代器、增强for(是JDK1.5以后出现的)。
Map:键找值。
6:遍历代码体现举例:
A:
ArrayList<String> array = new ArrayList<>();//采用泛型,此种写法符合JDK1.7新特性。
ArrayList<String> array = new ArrayList<String>();//与上面的写法都可以,只不过上面的写法是JDK1.7新特性。
方式1:
Iterator<String> it = array.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
方式2:
for(String s : array){
System.out.println(s);
}
方式3:
for(int x=0; x<array.size(); x++){
String s = array.get(x);
System.out.println(s);
}
B:
HashSet<String> hs = new HashSet<String>();
方式1:
Iterator<String> it = hs.iterator();//根据上面迭代器源码这里是多态的体现。
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
方式2:
for(String s : hs)
{
System.out.println(s);
}
C:
HashMap<String,Strting> hm = new HashMap<String,String>();
Set<String> set = hm.keySet();
for(String key : set)
{
String value = hm.get(key);
System.out.println(key+"***"+value);
}
7:什么时候用谁?
是否键值对?
是:Map
是否对键排序?
是:TreeMap
否:HashMap
否:Collection
是否唯一
是:Set
是否对元素进行排序?
是:TreeSet
否:HashSet
否:List
是否要安全:
是:Vector(真正开发中也不用)
List list = Collections.synchronizedList(new ArrayList());
否:ArrayList,LinkedList
查询多:ArrayList
增删多:LinkedList
8:Collections:
是一个类,定义了针对Collection集合操作的功能。该类中的方法都是静态的,有排序,查找,反转等。
Collections的功能:
排序:public static void sort(List list)
二分查找:public static <T> int binarySearch(List list,T key)
反转:public static void reverse(List list)
最大值:public static T max(Collection coll)
随机置换:public static void shuffle(List list)
9:在集合中的数据结构问题
ArrayXxx:底层数据结构是数组。查询快,增删慢。
LinkedXxx:底层数据结构是链表。查询慢,增删快。
HashXxx:底层数据结构是哈希表。跟两个有关。hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种排序方式。Comparable接口和Comparator接口