------- android培训、java培训、期待与您交流! ----------
集合的出现:
在java语言中,对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象的一种方式。
集合就是一个容器,用来存储对象,数组也是一个容器,也可以用来存储对象。
但是数组跟集合的差别就是:
数组的长度是固定的,数组中可以存储基本数据类型。
集合的长度是可变的,只能存储对象。
集合框架 Collection:
Collection是一个接口,里面定义了一些对集合操作的基本方法,以下是对基本方法的应用:
public static void baseMethod(){
//用collection的子类创建实例对象
Collection col = new ArrayList();
Collection col1 = new ArrayList();
//添加一个元素,添加的都是对象的引用
col.add("java01");
col.add("java04");
col1.add("java02");
col1.add("java03");
sop(col);
//将col1中所有的元素都添加到col中
col.addAll(col1);
sop(col);
//获取集合的长度,
sop(col.size());
//判断集合是否包含某个元素
sop(col.contains("java01"));
//col中是否包含col1中的所有元素
sop(col.containsAll(col1));
//判断集合是否为空
sop(col.isEmpty());
//将集合清空,删除所有元素
col.clear();
//删除某个元素
col.remove("java01");
//删除col跟col1中的相同元素
col.removeAll(col1);
sop(col);
//保留col和col1中的相同元素
col.retainAll(col1);
}
集合中获取元素的方法:
迭代器的概念:就是集合去除元素的方式。在迭代时,不可以通过集合对象的方法操作集合中的元素,
因为会发生ConcurrentModificationException异常,所以在迭代时只能使用迭代器的方法操作元素。
public static void getEle(){
Collection col = new ArrayList();
col.add("java01");
col.add("java04");
col.add("java02");
col.add("java03");
//得到迭代器 it
Iterator it = col.iterator();
//判断是否还有下一个元素,如果有就返回true
while(it.hasNext()){
/*
* 将对象获取出来,可以进行对象的操作,
* 这里不要出现获取多次对象的操作。
* 同时这里也不要再对集合进行操作。
* 例如:col.add()等。
*/
sop(it.next());
}
//另一种获取元素的方式,这样会节省点内存
for(Iterator it1 = col.iterator();it1.hasNext();){
it1.next();
}
}
以上是Collection中的一些共性方法,接下来是具体的子类实现。根据不同的需求和不同的数据结构,派生出了几个常用的子类。
Collection
|--List:List也是一个接口。在List中存储的元素是有序的,同时元素可以重复,因为这个集合体系有索引。
|--Set:Set也是一个接口。元素是无序的(存入和去除的顺序不一定一致),但是元素不可以重复。
List中的特有方法:
凡是可以操作角标的都是该体系的特有方法
增加:add(index,element)
addAll(index,Collection)
删除:remove(index)
更改:set(index,element)
查找:get(index)
subList(from,to)
listIterator()
public static void onlyListMethod(){
List list = new ArrayList();
List list1 = new ArrayList();
list.add("java01");
list.add("java04");
list1.add("list1---java02");
list1.add("list1---java03");
//在角标为1的位置插入元素
list.add(1,"java05");
sop(list);
//在角标为2的位置插入list1中的所有元素
list.addAll(2,list1);
sop(list);
//删除角标为3的元素
list.remove(3);
//修改角标为2处的元素
list.set(2, "java set");
//获取角标为1的元素
sop(list.get(1));
//获取角标为1,2的元素,包含头不包含尾
List subList = list.subList(1, 3);
sop(subList);
//得到list集合的迭代器
ListIterator lit = list.listIterator();
while(lit.hasNext()){
String str = (String)lit.next();
if("java set".equals(str)){
lit.remove();//删除元素操作
/*
* 添加元素的操作,只用在ListIterator中可以做添加动作
* 还有也可以做set操作
*/
lit.add("java lit");
}
}
sop(list);
//ListIterator还有倒序迭代
while(lit.hasPrevious()){
sop(lit.previous());
}
}
List集合中具体子类的特点:
List
|-- ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快,但是增删稍慢,线程不同步
|--LinkedList:底层使用的是链表的数据结构,特点:增删速度很快,查询稍慢
|--Vector:底层是数组结构,线程同步的,安全,被ArrayList替代了
List集合中判断元素是否相同的contains方法,其实就是调用元素的equals方法
LinkedList中的一些特有方法:
addFirst() addLast()
在头部和尾部添加元素
getFirst() getLast()
获取元素但不删除元素,如果集合中没有元素,出现NoSuchElementException异常
removeFirst() removeLast()
获取元素,但是元素被删除,如果集合中没有元素,出现NoSuchElementException异常
offerFirst() offerLast()
jdk1.6之后的新特性,替换了addFirst和addLast
peekFirst() peekLast()
获取元素,但是不删除元素,如果集合中没有,返回null
poolFirst() poolLast()
获取元素,但是元素被删除,如果集合中没有,返回null.
public static void linkedMethod(){
LinkedList llist = new LinkedList();
//在链表的头部插入
llist.addFirst("java01");
llist.addFirst("java02");
llist.addFirst("java03");
//打印结果"java03","java02","jav01"因为都是在头部插入
sop(llist);
//同理都是在尾部插入
llist.addLast("last01");
llist.addLast("last02");
llist.addLast("last03");
sop(llist);
//获取头部的元素
sop(llist.getFirst());
//获取尾部的元素
sop(llist.getLast());
//删除并获取头部的元素
sop(llist.removeFirst());
//删除并回去尾部的元素
sop(llist.removeLast());
//在头部和尾部插入元素
llist.offerFirst("offer f");
llist.offerLast("offer l");
sop(llist);
LinkedList llist1 = new LinkedList();
//获取头部和尾部元素,返回null
sop(llist1.peekFirst());
sop(llist1.peekLast());
//获取并删除头部和尾部,返回null
sop(llist1.pollFirst());
sop(llist1.pollLast());
}
Set集合的一些特点:
Set的基本方法跟Collection基本相同。
Set
|--HashSet 底层是哈希表结构的
HashSet保证元素的唯一性:
通过元素的两个方法,hashCode()和equals()方法来完成的
如果HashCode值相同,再去判断equals是否为true
如果HashCode值不同,就不会调用equals
注意:对于判断元素是否存在,以及删除的操作,依赖的方法时元素的HashCode和equals。
所以往HashSet中存入的元素,一般都要复写这两个方法。
|--TreeSet 底层是二叉树结构的,可以对存进去的元素进行排序。
保证元素的唯一性,就是元素的compareTo方法,返回0
或者是自定义比较器的compare 方法
但是元素必须具备可比较性,或者是集合自己接受一个比较器。
自定义比较器:实现Comparator接口,复写compare方法
import java.util.Comparator;
import java.util.HashSet;
import java.util.TreeSet;
class Person implements Comparable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
Person(String name,int age){
this.name = name;
this.age = age;
}
/*
* 复写hashCode和equals方法
* */
public int hashCode(){
return name.hashCode()+age*17;
}
public boolean equals(Object obj){
if(!(obj instanceof Person))
throw new RuntimeException("数据错误");
Person p = (Person)obj;
return this.name == p.getName() && this.age == p.getAge();
}
public String toString(){
return name+" "+age;
}
/*
* 复写compareTo方法,
* 返回:正数 当前元素的年龄大
* 负数 当前元素的年龄小
* 0 两个元素的年龄相等
* 当年龄相等时,判断姓名。
* 注意:在主要条件一致是,一定要判断次要条件。
* */
public int compareTo(Object obj) {
if(!(obj instanceof Person))
throw new RuntimeException("数据错误");
Person p = (Person)obj;
int i = this.age-p.getAge();
if(i==0)
return this.name.compareTo(p.getName());
return i;
}
}
/*
* 定义自己的比较器,实现Comparator接口。
* 按照年龄排序,从大到小
* 当元素自身有比较的方法,在创建TreeSet时,再传入一个自定义的比较器时
* 按照自定义的排序
* */
class MyCom implements Comparator{
@Override
public int compare(Object obj, Object obj1) {
if(!(obj instanceof Person) || !(obj1 instanceof Person) )
throw new RuntimeException("数据错误");
Person p = (Person)obj;
Person p1 = (Person)obj1;
int i = p1.getAge()-p.getAge();
if(i==0)
return p1.getName().compareTo(p.getName());
return i;
}
}
public class HashSetDemo {
public static void main(String[] args) {
treeSetMethod();
}
public static void hashCodeMethod(){
HashSet hs = new HashSet();
hs.add(new Person("张三",20));
hs.add(new Person("王五",25));
hs.add(new Person("李四",30));
//这个元素存不进去,存储失败返回false
sop(hs.add(new Person("张三",20)));
sop(hs);
}
public static void treeSetMethod(){
//创建TreeSet对象时,加入自定义的比较器
TreeSet ts = new TreeSet(new MyCom());
ts.add(new Person("张三",20));
ts.add(new Person("王五",25));
ts.add(new Person("李四",30));
//元素存不进去,判断的是Person的compareTo方法返回的是否是0
sop(ts.add(new Person("张三",20)));
sop(ts);
}
public static void sop(Object obj){
System.out.println(obj);
}
}
Map集合:该集合中存储键值对,一对一对往里存储。而且要保证键的唯一性。
Map
|--Hashtable:底层是哈希表数据结构,不可以存入null键和null值,该集合是线程同步的,效率低
|--HashMap:底层是哈希表数据结构,允许使用null键和null值,该集合是不同步的,效率高
|--TreeMap:底层是二叉树数据结构,线程不同步。可以用于给map集合进行排序
Map的方法:
获取Map全部元素的两种方式:
1 keySet :将map中的所有键存入set集合,让set迭代器取出所有的键,再用get方法获取值
2 entrySet:将键和值的映射关系存入set集合,关系类型就是Map.Entry,然后通过
getKey和getValue来获取全部元素。
public static void mapMethod(){
Map map = new HashMap();
//添加元素,添加时出现相同的键,后添加的值会覆盖先添加的值
//并且put方法会返回被覆盖的值
map.put("java01", "01");
sop(map.put("java01", "04"));
map.put("java02", "02");
sop(map);
//判断是否存在相同的键或者值
sop(map.containsKey("java01"));
sop(map.containsValue("01"));
//根据键来查找值
sop(map.get("java01"));
//删除键的值,
map.remove("java02");
sop(map);
//第一种 :取出所有元素
Set s = map.keySet();
Iterator it = s.iterator();
while(it.hasNext()){
String key = (String)it.next();
String value = (String)map.get(key);
sop(key+"--keyset方法--"+value);
}
//第二种:取出所有元素
Set s1 = map.entrySet();
Iterator it1 = s1.iterator();
while(it1.hasNext()){
Map.Entry entry = (Map.Entry)it1.next();
sop(entry.getKey()+"--entrySet方法--"+entry.getValue());
}
}
集合框架的工具类Collections:
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> list = new ArrayList<String>();
list.add("abc");
list.add("ac");
list.add("z");
list.add("zacde");
sop(list);
//按照自然顺序排序
Collections.sort(list);
sop(list);
//反转自然的顺序
Collections.reverse(list);
sop(list);
//反转元素继承的comparable接口的比较顺序
Collections.sort(list,Collections.reverseOrder());
sop(list);
//反转自定义比较器的顺序
Collections.sort(list,Collections.reverseOrder(new sortCom()));
sop(list);
//传入一个比较器,按照自己定义的方式排序
Collections.sort(list,new sortCom());
sop(list);
//折半查找,list必须是有序的,如果元素不是按照自然顺序排的,
//需要再传入一个比较器,跟排序是同一个比较器。
sop(Collections.binarySearch(list,"zd"));
sop(Collections.binarySearch(list,"zd",new sortCom()));
//获取角标最小和最大的元素
sop(Collections.max(list));
sop(Collections.min(list));
//交换两个元素的位置
Collections.swap(list, 1, 2);
sop(list);
//将元素的顺序打乱,随机的
Collections.shuffle(list);
sop(list);
//将list全部替换成指定元素
Collections.fill(list, "haha");
sop(list);
//将集合中的某一个值全部替换
Collections.replaceAll(list,"haha","heihei");
sop(list);
//返回线程同步的list集合
list = Collections.synchronizedList(list);
}
public static void sop(Object obj){
System.out.println(obj);
}
工具类Arrays:
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {3,2,4,1,7,6,9};
Integer[] arr1 = {3,2,4,1,7,6,9};
//返回数组的字符串形式
//sop(Arrays.toString(arr));
/*
* 把数组变成集合,
* 可以使用集合的思想来操作数组中的元素
* 注意:不可以使用数组中的增删方法,
* 因为数组的长度是固定的。
* 如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接变成集合中的元素
* 如果数组中的元素是基本数据类型,那么会将该数组最为集合中的元素存在。
* */
List<int[]> list = Arrays.asList(arr);
sop(list);
List<Integer> list1 = Arrays.asList(arr1);
sop(list);
/*
* 将集合变成数组,也是为了限定元素,不需要再进行增删了
* 指定数组的长度:集合的长度最优
* */
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
String[] sarr = al.toArray(new String[al.size()]);
sop(Arrays.toString(sarr));
}