集合框架


集合框架
集合在Java编程中非常重要所以必须掌握。
集合框架的由来:对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定需要用集合来存储。
集合的特点:
1.用于存储对象的容器
2.集合的长度是可变的
3.不能存储基本数据类型

集合容器因为内部的数据结构不同可以分为三大类List Set Map.
 List继承自Collection,是一个接口。实现该接口的类中的元素都是有序的此接口的用户可以对列表中每个元素的插入位置进行精确地控制。 用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素Set 存放的是对象的引用,而且对象没有排序,没有重复。 主要实现类是HashSet和TreeSet Map:Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。从概念上而言, 可以将 List 看作是具有数值键的 Map。而实际上,除了 List 和 Map 都在定义 java.util 中外,两者并没有直接的联系。
关系图:

Map关系图:

  Collection是Java集合框架中的父接口
 Collection的常见方法:
1.添加
 boolean add(Object obj); 添加一个对象
 boolean addAll(Collection coll); 添加一组对象
2.删除
 boolean remove(Object obj);删除一个对象
 boolean removeAll(Collection coll);删除一组对象
3.判断
 boolean contains(Object obj);是否包涵一个对象
 boolean containsAll(Collection coll);是否包涵一组对象
 boolean isEmpty();判断集合中是否有元素
4.获取
int size();获取集合的大小
Iterator iterator() 迭代集合返回一个迭代器对象
boolean retainAll(Colleaction coll);获取两个集合中的交集
Object[] toArray();将集合转化为数组

迭代器的使用
Collection coll=new ArrayList();
coll.add("a1");
coll.add("a2");
coll.add("a3");
coll.add("a4");
使用Collection中的iterator()方法。调用结合中的迭代器方法,获取集合中的迭代器对象
Iterator it=coll.iterator();
while(it.hasNext()){//hasNext()表示如果有元素可以迭代,则返回 true
System.out.println(it.next());//next()返回迭代中的下一个元素
}

通过While循环可以方便的取出集合中的所有元素,但是Iterator it=coll.iterator();中的it对象,在循环结束后一直保留在内存中所以推荐使用for循环迭代,it在for循环的条件之中,当循环结束后,it对象可以被回收,减少资源占用。如果循环结束后还想继续使用迭代器则使用while循环迭代。
for(Iterator it=coll.iterator();it.hasNext();){
System.out.println(it.next());
}

迭代器的原理
Collection接口中的iterator方法能够迭代集合,但是怎么迭代,它自己是不清楚的,所以必须依赖于自己的实现类,不同的实现类迭代的方式都不相同,所以迭代器对象是在具体容器中进行的内部实现,对于使用容器者而言,具体的实现并不重要,只要通过获取到该实现的迭代器对象即可,也就是iterator方法。Iterator接口是对所有的Collection容器进行元素取出的公共接口。

迭代器并发修改时的异常:java.util.ConcurrentModificationException

解决该问题的方法就是在迭代的时候不能调用集合的方法,而是调用迭代器自己的方法,但是Iterator接口本身的方法只有三个,有一定的局限性,这时可以使用Iterator的子接口ListIterator:列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。ListIterator 没有当前元素;它的光标位置 始终位于调用 previous() 所返回的元素和调用 next() 所返回的元素之间.ListIterator<String>it=list.listIterator();调用it的add方法进行添加元素,set方法修改元素,remove方法修改元素.只有List的集合具有该迭代功能

List集合:
List底层是有序的,表示数据怎么存放进去的,也就是怎么取出来。存入和取出的顺序一致元素都有索引,而且可以重复

List常见方法:
1,添加
void add(index,e);
void add(index,collection);
2,删除
Object remove(index);返回的是被删掉的那个元素;
3,修改
Object set(index,e);该方法只有List集合具有
4 获取
Object get(index);
int indexOf(object)
int lastIndexOf(object);
List subList(from,to);包含头不包含尾


List的三个常用子类
Vector:内部是数组数据结构,线程安全的,查询,增删都很慢
ArrayList:内部是数组数据结构,线程不安全的,替代Vector,遍历元素速度较快,判断元素是否相同,仅依据对象的equals方法
LinkedList内部是链表数据结构,线程不安全的,增加和删除元素的速度较快
Set集合:
元素不能重复,无序
Set的两个常用子类
HashSet:底层数据结构是哈希表,是无序的,可以有null元素,线程不安全的,判断元素是否相同依据hashCode和equals方法.
如果有元素存放到HashSet方法中必须覆盖hashCode和equals方法建立对象是否相同的依据。
LinkedHashSet:HashSet的子类,既能保证有序,也能保证不重复.
TreeSet:底层数据结构是二叉树,可以对集合中的元素进行指定顺序的排序,线程非安全的,判断是元素唯一的性的方式,就是根据比较方法的返回结果是否是0,是0则为相同元素。存放到TreeSet的对象必须实现Comparable接口,复写ComparTo方法来提供该类具体的
比较方法
TreeSet第一种排序方法:让元素自身具备比较性,实现Comparable接口复写ComparTo方法
示例:@Override
public int compareTo(Object o) {
Person p=(Person)o;
  if(!(p instanceof Person)){
       throw new RuntimeException("传递的对象类型不匹配");
}
 return this.age-p.age==0?this.name.compareTo(p.name):this.age-p.age;
}

TreeSet第二种排序方法:当元素自身不具备比较性时,或者不是我们需要的比较方式时可以让TreeSet集合具备比较功能按照姓名进行比较,如果姓名相同则比较年龄
Set<Person> set=new TreeSet<Person>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int temp=p1.getName().compareTo(p2.getName());
return temp==0?p1.getAge()-p2.getAge():temp;
}
});


Map集合:存储的是键值对,存储的键是唯一的
继承体系

常用方法:
1,添加
value put(key,value):返回前一个和key关联的值,如果同一个key对应多个value,后添加的value会覆盖掉前面的value,如果没有返回null
2,删除
void clear();清空map集合
value remove(key),根据键删除键值对,返回被删除的值
3,判断
boolean containsKey(key);判断是否包涵键 
boolean containsKey(value);判断是否包涵值
4,获取
value get(key),根据键返回值,如果没有该键返回null
int size(),获取键值对的个数

keySet方法的原理:
entrySet方法的原理:

Map的values()方法。该方法返回Collection<value> ,将所有的值作为一个集合返回,因为键是唯一的,要用Set集合存储,但是值可以不唯一,用Collection存储。

HashTable和HashMap的区别:
HashTable是jdk1.0就出现的对象。底层数据结构为哈希表,而且不能存储null对象而且线程是同步的。
HashMap是jdk2.0出现的Map的一个实现类,底层也是哈希表,可以存储最多一个null键,多个null值的元素,线程是
不同步的。一般情况下会使用HashMap,虽然不是同步的但是执行效率和功能比HashTable要好。如果需要同步则。可以通过
Collections工具类中的synchronizedMap方法将map对象作为参数传递,返回一个线程安全的Map对象.
Map m = Collections.synchronizedMap(new HashMap());
Set s = m.keySet();  // Needn't be in synchronized block
synchronized(m) {  // 同步锁必须是map对象m而不是键s
    Iterator i = s.iterator(); // 迭代元素时必须放在同步代码块中
    while (i.hasNext())
        foo(i.next());
}

HashTable的子类:Properties
用来存储键值对型的配置文件信息,可以通过I/O来加载程序中的配置文件获取文件中的键值对
	private static Properties properties = new Properties();

	static {
		FileInputStream inStream = null;
		try {
			//获取配置文件的路径
			String filePath = BeanFactory.class.getClassLoader().getResource("BeanFactory.properties").getPath();
			inStream = new FileInputStream(filePath);
			//加载到配置文件
			properties.load(inStream);
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (inStream != null) {
				try {
					inStream.close();//关闭流
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}
	}

Collections工具类:

Collections是集合框架中的一个工具类,提供的全部是静态方法,方便使用者调用,可以进行对集合的排序,搜索,以及构建线程安全的集合对象
①对list集合进行排序
Collections.sort(list);
sort方法的实现:
  public static <T extends Comparable<? super T>> void sort(List<T> list) {
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
   i.next();
   i.set((T)a[j]);
}
    }
 sort方法可以传递一个list集合,这个集合找那个可以存储任意类型的元素,但是必须限定<T extends Comparable<? super T>> 这个任意元素必须是Comparable的子类 ,这样才具备比较性才能排序,Comparable<? super T>中使用泛型的边界定义,可以使用T排序,同时也可以使用T的父类排序。Object[] a = list.toArray();Arrays.sort(a);将list集合转化为数据,再调用数组的排序方法,这样就不需要 单独定义排序方法。在通过List的集合迭代器将数组中的排序后的元素添加到集合中。sort方法还有一个重载方法,可以指定一个比较器,来按照指定顺序比较
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值