Collection集合框架的结构

Collection集合框架包含2个接口:

        Collection:List列表,Set集

        Map:Hashtable,HashMap,TreeMap

 Collection  是单列集合

List   元素是有序的、可重复

        有序的 collection,可以对列表中每个元素的插入位置进行精确地控制。

        可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。 

        可存放重复元素,元素存取是有序的。

List接口中常用类:

        l Vector: 线程安全,但速度慢,已被ArrayList替代。

底层数据结构是数组结构

        l ArrayList:线程不安全,查询速度快。

            底层数据结构是数组结构

        l LinkedList:线程不安全。增删速度快。

             底层数据结构是列表结构

Set(集) 元素无序的、不可重复。

        取出元素的方法只有迭代器。不可以存放重复元素,元素存取是无序的。

Set接口中常用的类:

        l HashSet:线程不安全,存取速度快。

          它是如何保证元素唯一性的呢?依赖的是元素的hashCode方法和euqals方法。

        l TreeSet:线程不安全,可以对Set集合中的元素进行排序。

          它的排序是如何进行的呢?通过compareTo或者compare方法中的来保证元素的唯一性。元素是以二叉树的形式存放的。

Map  是一个双列集合

        |--Hashtable:线程安全,速度快。底层是哈希表数据结构。是同步的。

不允许null作为键,null作为值。

        |--Properties:用于配置文件的定义和操作,使用频率非常高,同时键和值都是字符串。

是集合中可以和IO技术相结合的对象。(到了IO在学习它的特有和io相关的功能。)

        |--HashMap:线程不安全,速度慢。底层也是哈希表数据结构。是不同步的。

允许null作为键,null作为值。替代了Hashtable.

        |--LinkedHashMap: 可以保证HashMap集合有序。存入的顺序和取出的顺序一致。

        |--TreeMap:可以用来对Map集合中的进行排序.

Collection接口 和 Collections类的区别:

        Collection是集合类的上级接口,子接口主要有Set 和List

        Collections是针对集合类的一个帮助类,提供了操作集合的工具方法:一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

---------------------------------------------------------------------------------------------------------------------------------------------------------

以下介绍接口:
List接口:(介绍其下的两个实现类:ArrayList和LinkedList)
ArrayList和数组非常类似,其底层①也用数组组织数据,ArrayList是动态可变数组。
底层:指存储格式。说明ArrayList对象都是存在于数组中。
注:数组和集合都是从下标0开始。
ArrayList有一个add(Object o)方法用于插入数组。
ArrayList的使用:(完成这个程序)
先import  java.util.*;
用ArrayList在一个数组中添加数据,并遍历。
ArrayList中数组的顺序与添加顺序一致。
只有List可用get和size。而Set则不可用(因其无序)。
Collection接口都是通过Iterator()(即迭代器)来对Set和List遍历。
通过语句:Iterator it=c.iterator(); 得到一个迭代器,将集合中所有元素顺序排列。然后可以通过interator方法进行遍历,迭代器有一个游标(指针)指向首位置。
Interator有hasNext(),用于判断元素右边是否还有数据,返回True说明有。然后就可以调用next动作。Next()会将游标移到下一个元素,并把它所跨过的元素返回。(这样就可以对元素进行遍历)
练习:写一个程序,输入对象信息,比较基本信息。
集合中每一个元素都有对象,如有字符串要经过强制类型转换。
Collections是工具类,所有方法均为有用方法,且方法为static。
有Sort方法用于给List排序。
Collections.Sort()分为两部分,一部分为排序规则;一部分为排序算法。
规则用来判断对象;算法是考虑如何排序。
对于自定义对象,Sort不知道规则,所以无法比较。这种情况下一定要定义排序规则。方式有两种:
java.lang下面有一个接口:Comparable(可比较的)
可以让自定义对象实现一个接口,这个接口只有一个方法comparableTo(Object o)
其规则是当前对象与o对象进行比较,其返回一个int值,系统根据此值来进行排序。
如 当前对象>o对象,则返回值>0;(可将返回值定义为1)
如 当前对象=o对象,则返回值=0;
如 当前对象<o对象,则返回值〈0。(可将返回值定义为-1)
看TestArraylist的java代码。
我们通过返回值1和-1位置的调换来实现升序和降序排列的转换。


java.util下有一个Comparator(比较器)
它拥有compare(),用来比较两个方法。
要生成比较器,则用Sort中Sort(List,List(Compate))
第二种方法更灵活,且在运行的时候不用编译。


注意:要想实现comparTo()就必须在主方法中写上implement comparable.


练习:生成一个EMPLOYEE类,然后将一系列对象放入到ArrayList。用Iterator遍历,排序之后,再进行遍历。


集合的最大缺点是无法进行类型判定(这个缺点在JAVA1.5中已经解决),这样就可能出现因为类型不同而出现类型错误。
解决的方法是添加类型的判断。


LinkedList接口(在代码的使用过程中和ArrayList没有什么区别)
ArrayList底层是object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。
而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。
双向循环链表的查询效率低但是增删效率高。所以LinkedList具有查询效率低但增删效率高的特点。
ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。
LinkedList经常用在增删操作较多而查询操作很少的情况下:队列和堆栈。
队列:先进先出的数据结构。
堆栈:后进先出的数据结构。
注意:使用堆栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。
LinkedList提供以下方法:(ArrayList无此类方法)
addFirst();    
removeFirst();
  addLast();
  removeLast();
在堆栈中,push为入栈操作,pop为出栈操作。


Push用addFirst();pop用removeFirst(),实现后进先出。
用isEmpty()--其父类的方法,来判断栈是否为空。


在队列中,put为入队列操作,get为出队列操作。
Put用addFirst(),get用removeLast()实现队列。


List接口的实现类(Vector)(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。)
结论:在考虑并发的情况下用Vector(保证线程的安全)。
在不考虑并发的情况下用ArrayList(不能保证线程的安全)。


面试经验(知识点):
java.util.stack(stack即为堆栈)的父类为Vector。可是stack的父类是最不应该为Vector的。因为Vector的底层是数组,且Vector有get方法(意味着它可能访问到并不属于最后一个位置元素的其他元素,很不安全)。
对于堆栈和队列只能用push类和get类。
Stack类以后不要轻易使用。
!!!实现堆栈一定要用LinkedList。
(在JAVA1.5中,collection有queue来实现队列。)


Set-HashSet实现类:
遍历一个Set的方法只有一个:迭代器(interator)。
HashSet中元素是无序的(这个无序指的是数据的添加顺序和后来的排列顺序不同),而且元素不可重复。
在Object中除了有final(),toString(),equals(),还有hashCode()。
HashSet底层用的也是数组。
当向数组中利用add(Object o)添加对象的时候,系统先找对象的hashCode:
int hc=o.hashCode(); 返回的hashCode为整数值。
Int I=hc%n;(n为数组的长度),取得余数后,利用余数向数组中相应的位置添加数据,以n为6为例,如果I=0则放在数组a[0]位置,如果I=1,则放在数组a[1]位置。如果equals()返回的值为true,则说明数据重复。如果equals()返回的值为false,则再找其他的位置进行比较。这样的机制就导致两个相同的对象有可能重复地添加到数组中,因为他们的hashCode不同。
如果我们能够使两个相同的对象具有相同hashcode,才能在equals()返回为真。
在实例中,定义student对象时覆盖它的hashcode。
因为String类是自动覆盖的,所以当比较String类的对象的时候,就不会出现有两个相同的string对象的情况。
现在,在大部分的JDK中,都已经要求覆盖了hashCode。
结论:如将自定义类用hashSet来添加对象,一定要覆盖hashcode()和equals(),覆盖的原则是保证当两个对象hashcode返回相同的整数,而且equals()返回值为True。
如果偷懒,没有设定equals(),就会造成返回hashCode虽然结果相同,但在程序执行的过程中会多次地调用equals(),从而影响程序执行的效率。


我们要保证相同对象的返回的hashCode一定相同,也要保证不相同的对象的hashCode尽可能不同(因为数组的边界性,hashCode还是可能相同的)。例子:
public int hashCode(){
  return name.hashcode()+age;
}
这个例子保证了相同姓名和年龄的记录返回的hashCode是相同的。


使用hashSet的优点:
hashSet的底层是数组,其查询效率非常高。而且在增加和删除的时候由于运用的hashCode的比较开确定添加元素的位置,所以不存在元素的偏移,所以效率也非常高。因为hashSet查询和删除和增加元素的效率都非常高。
但是hashSet增删的高效率是通过花费大量的空间换来的:因为空间越大,取余数相同的情况就越小。HashSet这种算法会建立许多无用的空间。
使用hashSet接口时要注意,如果发生冲突,就会出现遍历整个数组的情况,这样就使得效率非常的低。


练习:new一个hashset,插入employee对象,不允许重复,并且遍历出来。


添加知识点:
集合对象存放的是一系列对象的引用。
例:
Student S
Al.add(s);
s.setName(“lucy”);
Student s2=(Student)(al.get(o1));

可知s2也是s。

---------------------------------------------------------------------------------------------------------------------------------------------------------

1. Collection框架中实现比较要实现什么接口?Comparable/comparator

2. ArrayList和Vector的区别?

这两个类都实现了List接口,List接口继承了Collection接口,他们都是有序集合.即存储在这两个集合中的元素的位置都是由顺序的,相当于一种动态的数组,我们以后可以按位置索引号来取出某个元素,并且其中的数据是允许重复的.这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素.也不允许有重复的元素.本题目本与hashset没有任何关系,但为了说清楚ArrayList和Vector的功能,我们使用对比方式,有利于说明问题.

接着才说ArrayList与Vector的区别,主要包括两个方面:

(1)同步性

Vector是线程安全的,也就是说它的方法之间线程同步.而ArrayList是先程序不安全的,它的方法之间的线程数不同步的,如果只有一个线程会访问到集合,那么最好用ArrayList,因为它不考虑线程安全,效率会高些.如果有多个线程会访问到集合,那么就使用Vector,因为不需要我们自己去考虑和编写线程安全代码.

备注:对于Vector和ArrayList,Hashtable和HashMap,线程安全是前2个,记住Vector和Hashtable是旧的,是java一诞生就提供了的,他们是线程安全的.而Arratlist和HashMap是java2才提供的,他们是线程不安全的.

(2)数据增长

ArrayList和Vector都有一个初始的容量大小,但存储进他们里面的元素的个数超过了容量时,就需要增加ArrayList和Vector的存储空间,每次要增加时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间里同和程序效率之间要取得一定的平衡.Vector增长为原来的一倍,ArrayList增加原来的0.5倍.

3. HshMap和Hashtable的区别?

HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。

HashMap允许将null作为一个entry的key或者value,而Hashtable不允许.总之有三条:

一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java1.2引进的Map接口的一个实现
二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
三.值:只有HashMap可以让你将空值作为一个表的条目的key或value

4. List和Map的区别?

一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,

List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。

5、List, Set, Map是否继承自Collection接口?

List,Set是,Map不是

6.List、Map、Set三个接口,存取元素时,各有什么特点?

List 以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map保存key-value值,value可多值。

1. 说出ArrayList,Vector,LinkedList的存储性能和特性

ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用。

4、去掉一个Vector集合中重复的元素

Vector newVector =new Vector();

For (inti=0;i<vector.size();i++)

{

Object obj =vector.get(i);

if(!newVector.contains(obj);

newVector.add(obj);

}

还有一种简单的方式,HashSet set = new HashSet(vector);

9、Collection和 Collections的区别。

  Collection是集合类的上级接口,继承与他的接口主要有Set 和List.

Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

10.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()?它们有何区别?

Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。

equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

11.你所知道的集合类都有哪些?主要方法?

最常用的集合类是List 和 Map。 List 的具体实现包括 ArrayList 和Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List适用于按数值索引访问元素的情形。

Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。

ArrayList/VectoràList

àCollection

HashSet/TreeSetàSet

PropetiesàHashTable

àMap

Treemap/HashMap

对于set,大概的方法是add,remove,contains;对于map,大概的方法就是put,remove,contains等,因为,我只要在eclispe下按点操作符,很自然的这些方法就出来了。我记住的一些思想就是List类会有get(intindex)这样的方法,因为它可以按顺序取元素,而set类中没有get(intindex)这样的方法。List和set都可以迭代出所有元素,迭代时先要得到一个iterator对象,所以,set和list类都有一个iterator方法,用于返回那个iterator对象。map可以返回三个集合,一个是返回所有的key的集合,另外一个返回的是所有value的集合,再一个返回的key和value组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value。

12、两个对象值相同(x.equals(y)==true),但却可有不同的hashcode,这句话对不对?

对。

如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。

如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如arrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。

13、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常!

(应该是没有针对问题的确切的答案,当前的add方法放入的是哪个对象,就调用哪个对象的compareTo方法,至于这个compareTo方法怎么做,就看当前这个对象的类中是如何编写这个方法的)

实验代码:

public class Parent implementsComparable {

private int age = 0;

public Parent(int age){this.age = age; }

public int compareTo(Objecto) {

System.out.println("method of parent");

Parento1 = (Parent)o;

returnage>o1.age?1:age<o1.age?-1:0; }}

public class Child extendsParent {

public Child(){super(3); }

public int compareTo(Objecto) {

System.out.println("method of child");

// Childo1 = (Child)o;

return 1; }}

public class TreeSetTest {

public static void main(String[]args) {

TreeSetset = new TreeSet();

set.add(new Parent(3));

set.add(new Child());

set.add(new Parent(4));

System.out.println(set.size()); } }


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值