黑马程序员---java基础之集合Collection

------- android培训java培训、期待与您交流! ----------

集合(collection)

集合是存储对象的最常用的一种方式

集合与数组的区别

1-数组虽然可以存储对象,但长度是固定的,集合长度是可变的.

2-数组中可以存储基本数据类型,集合只能存储对象.

集合的特点

1-集合只用于存储对象

2-集合长度是可变的

3-集合可以存储不同类型的对象

集合体系:

Collection

|-List

    |-ArrayList

    |-LinkedList

    |-Vector:被ArrayList替代了。因为效率低。

|-Set

    |-HashSet

    |-TreeSet

Collection定义了集合框架的共性功能。

1,添加
add(e);添加元素
addAll(collection);将指定 collection 中的所有元素都添加到此 collection 中
2,删除
remove(e);删除指定元素
removeAll(collection);
clear();移除此 collection 中的所有元素
3,判断。
contains(e); 如果此 collection 包含指定的元素,则返回 true
isEmpty();是否为空,空则返回true
4,获取
iterator();返回在此 collection 的元素上进行迭代的迭代器。
size();返回集合的长度
5,获取交集。
retainAll();仅保留此 collection 中那些也包含在指定 collection 的元素
6,集合变数组。
toArray();

迭代器

就是集合的取出元素的方式。  

迭代器是取出方式,会直接访问集合中的元素。

所以将迭代器通过内部类的形式来进行描述。

通过容器的iterator()方法获取该内部类的对象。

迭代时最好用for循环,内存更优化

Collection c = new ArrayList();
for(Iterator it = c.iterator();it.hasNext();){
System.out.println(it.next());
}

注意:
1,add方法的参数类型是Object。以便于接收任意类型对象。
2,集合中存储的都是对象的引用(地址)


List集合

List的特点:元素是有序的,元素可以重复。因为该集合体系有索引。

List集合判断元素是否相同,依据是元素的equals方法。
List特有方法:

凡是可以操作角标的方法都是该体系特有的方法。


add(index,element);将指定的元素插入此列表中的指定位置。
addAll(index,Collection);从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。

remove(index);移除此列表中指定位置上的元素。

set(index,element);用指定的元素替代此列表中指定位置上的元素。

get(index):返回此列表中指定位置上的元素。
subList(from,to); 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
listIterator();返回此列表元素的列表迭代器
int indexOf(obj):获取指定元素的位置。
ListIterator listIterator();

List集合特有的迭代器。
ListIterator是Iterator的子接口。

ArrayList al = new ArrayList();
for(ListIterator li = al.listIterator();li.hasNext();){
	System.out.println(li.next());
}
在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException异常。
在迭代时循环中next调用一次,就要hasNext判断一次。

所以,在用迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,
只能对元素进行判断,取出,删除的操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。
该接口只能通过List集合的listIterator方法获取。


1--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。

ArrayList的方法和List基本一致.

2--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。

LinkedList特有方法
addFirst()将元素添加到开头
addLast()将元素添加到结尾

getFirst()获取第一个元素
getLast()获取最后一个元素
如果列表异常,会出现NoSuchElementException

removeFirst()获取并删除第一个元素
removeLast()获取并删除最后一个元素
如果列表异常,会出现NoSuchElementException

JDK1.6出现了替代方法:推荐使用替代方法

peekFirst()获取第一个元素,如果列表为空,返回null
peekLast()获取最后一个元素,如果列表为空,返回null

pollFirst():获取并删除第一个元素,如果列表为空,返回null
pollLast()获取并删除最后一个元素,如果列表为空,返回null

3--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。

枚举(Enumeration)就是Vector特有的取出方式。其实枚举和迭代是一样的。

Vector v = new Vector();
for(Enumeration e = v.elements();e.hasMoreElements();){
	System.out.println(e.nextElement());
}
因为枚举的名称以及方法的名称都过长。所以被迭代器取代了。

Set集合

set集合的功能和collection是一致的
set集合的特点是:元素是无序(存入和取出的顺序不一定一致),元素不可以重复.

1--HashSet:底层数据结构是哈希表。是线程不安全的。线程不同步。

HashSet保证元素唯一性是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals。
注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。

import java.util.*;

class Main{
	public static void main(String[] args){
		Set set = new HashSet();
		set.add(new Personer("zhangsan",20));
		set.add(new Personer("zhangsan",20));//姓名年龄相同,添加不进集合
		set.add(new Personer("zhangsan",22));
		set.add(new Personer("zhangsan",23));
		for(Iterator it = set.iterator();it.hasNext();){
			System.out.println(it.next());
		}		
	}
}
class Personer{
	private String name;
	private int age;
	Personer(String name,int age){
		this.name = name;
		this.age = age;
	}
	//复写hashCode方法
	public int hashCode() {
		return name.hashCode()+age*10;
	}
	//复写equals方法,如果姓名年龄相同则为同一个人
	public boolean equals(Object obj) {
		Personer p = (Personer)obj;
		return this.name.equals(p.getName()) && this.age==p.getAge();
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public String toString(){
		return name+"--"+age;
	}
}

2--TreeSet:可以对Set集合中的元素进行排序。底层数据结构是二叉树。
保证元素唯一性的依据:compareTo()方法.如果返回0则是同一个元素
注意:排序时,当主要条件相同时,一定判断一下次要条件。
TreeSet在存储对象时,如果对象没有覆盖compareTo方法并且TreeSet初始化时没有传入比较器,会报错.
TreeSet排序的第一种方式
让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。也就是在创建类的时候直接定义比较规则
这种方式也成为元素的自然顺序,或者叫做默认顺序。
class Main{
	public static void main(String[] args){
		Set set = new TreeSet();
		set.add(new Personer("zhangsan",22));
		set.add(new Personer("lisi",20));
		set.add(new Personer("zhangsan",22));//姓名年龄相同,添加不进集合
		set.add(new Personer("wangwu",23));
		for(Iterator it = set.iterator();it.hasNext();){
			System.out.println(it.next());
		}
		/*运行结果:
			lisi--20
			wangwu--23
			zhangsan--22*/
	}
}
class Personer implements Comparable{//让该类对象具备比较方法
	private String name;
	private int age;
	Personer(String name,int age){
		this.name = name;
		this.age = age;
	}
	//复写CompareTo方法,按照姓名的自然顺序排序,如果姓名年龄都相同即为同一人
	public int compareTo(Object o) {
		Personer p = (Personer)o;
		int num = this.name.compareTo(p.getName());//比较名字是否相同
		if(num == 0)
			num = Integer.valueOf(this.age).compareTo(Integer.valueOf(p.getAge()));//如果相同再比较年龄
		return num;
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public String toString(){
		return name+"--"+age;
	}
}
TreeSet的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。在集合初始化时,就有了比较方式。
自定义比较器的方法:
自定义比较器:定义一个类,实现Comparator接口,覆盖compare方法。
class Main{
	public static void main(String[] args){
		//创建一个TreeSet集合,并传入一个比较器,以匿名内部类形式
		Set set = new TreeSet(new Comparator(){
			//复写compare方法,按照年龄的自然顺序排序
			public int compare(Object o1, Object o2) {
				Personer p1 = (Personer)o1;
				Personer p2 = (Personer)o2;
				int num = Integer.valueOf(p1.getAge()).compareTo(Integer.valueOf(p2.getAge()));//比较年龄
				if(num==0)
					num = p1.getName().compareTo(p2.getName());;//比较名字是否相同
				return num;
			}
		});
		set.add(new Personer("zhangsan",22));
		set.add(new Personer("lisi",20));
		set.add(new Personer("zhangsan",21));
		set.add(new Personer("wangwu",23));
		for(Iterator it = set.iterator();it.hasNext();){
			System.out.println(it.next());
		}
		/*运行结果:由于传入了比较器,以比较器的compare方法为主
			lisi--20
			zhangsan--21
			zhangsan--22
			wangwu--23*/
	}
}
class Personer {//没有实现Comparable接口,需要在集合初始化时传入比较器
	private String name;
	private int age;
	Personer(String name,int age){
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public String toString(){
		return name+"--"+age;
	}
}
当两种排序都存在时,以比较器为主。


总结:
容易混淆的知识点:
1--HashSet:
保证元素唯一性是通过元素的两个方法,hashCode和equals来完成。先比HashCode,相同的话再用equals比
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals。
定义类的时候如果需要存入HashSet中,必须复写hashCode和equals方法,定义自己的比较规则来保证元素的唯一性
2--TreeSet:
保证元素唯一性的依据:compareTo()方法.如果返回0则是同一个元素,负数是小于,正数是大于.
排序时,当主要条件相同时,一定判断一下次要条件。
两个前提:
1.要么对象继承Comparable接口复写compareTo()方法,
2.要么在初始化集合的时候传入一个比较器,复写compare方法

TreeSet在存储对象时,如果对象没有覆盖compareTo方法并且TreeSet初始化时没有传入比较器,会报错.
当两种排序都存在时,以比较器为主。




------- android培训java培训、期待与您交流! ----------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值