您的位置:首页 > 其它

集合部分的总结

2016-09-24 16:55 232 查看
数组是保存一组对象的最有效方式,特别是基本数据类型,但它的尺寸一般是固定的。如果不知道需要多少个对象,甚至不知道具体类型。为此Java提供了一套完整的容器类来解决这个问题。这些对容器类可以自动调整自己的尺寸,也称为集合类。简单说,根据数据结构的不同,集合分为单列集合和双列集合。

一.集合类型

1.单列集合

用于存放值,实现了顶层接口Collection,它拥有两个子接口,分别是List和Set。

List接口包含了2个常用的实现类,分别是:ArrayList、LinkedList.另外还有Vector,不过因为效率不高,使用的频率不很高

Set接口包含了2个常用的实现类,分别是:HashSet、TreeSet

单列集合的结构关系如下图所示:



2.双列集合

体现了一种映射关系,存放的是键-值对,实现了顶层接口Map,Map下面有两个常用的实现类:HashMap、TreeMap

集合使用的一般步骤:

1、创建集合

2、创建元素对象

3、把创建好的元素对象添加到集合中去

4、开始遍历

二.Collection接口

Collection是单列集合的顶层接口(实际还继承了Iterable接口),里面包含的方法有:

1、添加功能

      boolean add(E e):向集合中添加一个元素。

      boolean addAll(Collection c):将一个集合直接添加到该集合尾部。

2、删除功能

      void clear():删除集合中所有的元素。

      boolean remove(Object obj):删除集合中指定的元素。

      boolean removeAll(Collection c):删除集合中指定的子集合。

3、判断功能

      boolean isEmpty():判断集合是否为空。

      boolean contains(Object o):判断集合是否包含指定的元素。

      boolean containsAll(Collection c):判断集合中是否包含指定的子集合中的所有元素。

4、遍历功能

      Iterator<E> iterator():获取一个迭代器。

5、长度功能

      int size():获得集合的元素个数。

6、交集功能

      boolean retainAll(Collection c):判断两个集合是否有相同的元素,并且调用的集合中的元素会成为交集

7、转换功能

      Object[] toArray():把集合变成数组。

三. List接口及其实现类

List集合里面的元素是有序的,有索引的,可重复的。所以一般对存放的元素没有特殊要求的,可以考虑使用List集合。

常用的实现类有ArrayList和LinkedList,具体的应用场景:

如果增删操作很多,并且要求效率高,那么就使用LinkedList(因为LinkedList底层数据结构是链表数据结构)。

如果查找操作很多,并且要求效率高,那么就使用ArrayList(因为ArrayList底层数据结构是数组数据结构)。

使用ArrayList的例子:

//1 创建集合容器对象
ArrayList<String> al = newArrayList<String>();

//2创建元素对象

String s1 = "s1";

String s2 = "s2";

String s3 = "s3";

//3把创建好的元素对象,添加到集合当中

al.add(s1);

al.add(s2);

al.add(s3);

//4 遍历操作

//第一种遍历方式(使用Iterator,单列集合通用方式)

Iterator<String> iterator =al.iterator();

while(iterator.hasNext()) {

System.out.println(iterator.next());

}

//第二种遍历方式,List集合特有
ListIterator<String> listIterator= al.listIterator();

while(listIterator.hasNext()) {

System.out.println(listIterator.next());

}

//第三种遍历方式,List集合特有

for(intx=0;x<al.size();x++){

System.out.println(al.get(x));

}

//第四种遍历方式

for (String s: al) {

System.out.println(s);

}


使用LinkedList的例子:

//1创建集合容器对象

LinkedList<String> linkedList = newLinkedList<String>();

//2创建元素对象

String s1 = "s1";

String s2 = "s2";

String s3 = "s3";

//3把创建好的元素对象放到集合里面去

linkedList.add(s1);

linkedList.add(s2);

linkedList.add(s3);

//或者使用特有方法

linkedList.addFirst(s1);

linkedList.addFirst(s2);

linkedList.addFirst(s3);

//4遍历操作

Iterator<String> it =linkedList.iterator();

while (it.hasNext
be79
()){

System.out.println(it.next());

}


四. Set接口及其实现类

Set接口(集合)的特点是,里面的元素是无序的,不可重复的。无序的意思是:元素对象存进去和取出来的顺序不一致,而实际上元素存进去时,是按照一定的规则存放的。

具体的应用场景:

1、  如果仅仅是要求元素不能重复,那就可以直接使用HashSet

2、  如果要求元素不能重复,并且还要求能够排序,那就可以使用TreeSet

1.HashSet

HashSet底层的数据结构是哈希表,在存放元素时,想要存储唯一的元素,必须在元素对象所属的类中重写两个方法:hashCode()和equals(Object obj)方法。

假设使用HashSet来存放Person对象,则代码如下:

定义一个Person类,这个类实现了hashCode()方法和equals方法,如下所示:



class Person{

private String name;

private String weibo;

public String getName() {

return name;

}

…………

…………………………..

……………………

@Override

public int hashCode() {

final int prime =31;

int result =1;

result = prime * result +getOuterType().hashCode();

result = prime * result + ((name == null) ? 0 : name.hashCode());

result = prime * result + ((weibo == null) ? 0 : weibo.hashCode());

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if(getClass() != obj.getClass())

return false;

Person other = (Person) obj;

if(!getOuterType().equals(other.getOuterType()))

return false;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

if (weibo == null) {

if (other.weibo != null)

return false;

} else if (!weibo.equals(other.weibo))

return false;

return true;

}

private Demo getOuterType(){

return Demo.this;

}

}


*使用HashSet的例子

//创建HashSet集合容器

HashSet<Person> hashSet = newHashSet<Person>();

//创建元素对象

Person p1 = new Person("曾小贤", "zengxiaoxian@sina.com");

Person p2 = new Person("胡一菲", "huyifei@sina.com");

Person p3 = new Person("关谷", "guangu@sina.com");

//把创建好的元素对象,添加到HashSet里面去

hashSet.add(p1);

hashSet.add(p2);

hashSet.add(p3);

//遍历操作

Iterator<Person> iterator =hashSet.iterator();

while(iterator.hasNext()) {

Person person =  iterator.next();

System.out.println("姓名="+person.getName() + " 微博=" + person.getWeibo());

}

}

之所以是使用HashSet,是因为要求存放的元素对象是不重复的,而且不必要排序,那么就使用HashSet。一般元素之间的属性值一样时,就认为是重复元素。所以,必须重写equals(Objectobj)方法,为了效率,还必须重写hashCode()方法。当然,工作中貌似都是直接使用eclipse的自动生成代码功能~~~

2.使用TreeSet

实际上,TreeSet保证元素唯一,并不是靠元素对象的hashCode()方法和equals(Object obj)方法,而是靠下面两种办法来保证。

第一种方法:

使得元素对象对应的类,来实现一个接口:Comparable,并且实现Comparable接口的唯一的一个方法:compareTo()。这个方法返回值是0的话,就表示TreeSet里面有这个元素了,不可以存进去。返回值不是0,那就表示这个元素可以存进来。但是:返回值是1,和返回值是 -1,顺序刚好相反!



class Person implements Comparable<Person>{

private String name;

private String weibo;

@Override
public int compareTo(Person o) {

int num1 = this.name.compareTo(o.name);

if (num1==0){  // 如果比较的姓名一样的话,继续比较微博

int num2 = this.weibo.compareTo(o.weibo);

return num2;

}else{  //如果比较的姓名不一样,那就直接返回即可

return num1;

}

}

}

//创建TreeSet集合容器

TreeSet<Person> treeSet = new TreeSet<Person>();

//创建元素对象
Person p1 = new Person("曾小贤", "zengxiaoxian@sina.com");

Person p2 = new Person("胡一菲", "huyifei@sina.com");
//下面这个p3,实际上是存不进去的
Person p3 = new Person("曾小贤", "zengxiaoxian@sina.com");





第二种方法:

不需要使元素对象实现什么接口,只需要在创建TreeSet对象的时候,使用带Comparator参数的构造函数即可,其实就是匿名内部类,具体代码如下:

TreeSet<Person> treeSet = new TreeSet<Person>(new Comparator<Person>() {

public int compare(Person o1,Person o2) {

int n1 =o1.getName().compareTo(o2.getName());

//如果姓名不一样,那就表示两个人是两个不同对象,可以直接存放进去

if (n1 != 0) {

return n1;

//如果姓名一样,那就还要比较微博是否一样,把比较结果返回即可

}else{
return o1.getWeibo().compareTo(o2.getWeibo());

}

});

五. Map集合

Map集合是双列集合,在Java类库中也是一个接口,包含了两个常用的实现类:HashMap和TreeMap。

HashMap可以保证键值对中的键唯一,那么键对应的类,必须重写hashCode()和equals(Object obj)方法,没错,和HashSet一样的做法!这里要注意的是,Map只能存放引用类型的键值对,不能存放基本数据类型的键值对,之所以有时会看到的确存放了基本数据类型的键值对,那是因为JDK1.5之后的新特性:自动装箱。

TreeMap和之前学的TreeSet也有关联,实际上,TreeMap可以保证键值对中的键排序、唯一,那么键对应的类,必须实现Comparable接口,或者在使用TreeMap时,在创建TreeMap对象的时候,需要使用有Comparator参数的构造函数。

关于Map有哪些方法,这里就不详述了,有时间另写一篇






                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: