集合框架

来源:互联网 发布:对外汉语 知乎 编辑:程序博客网 时间:2024/06/04 18:44


一、集合类介绍
1、出现集合类的原因
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
2、集合和数组的区别
  • 数组虽然也可以存储对象,但长度是固定的;集合是可变长度的。
  • 数组中可以存储基本数据类型和对象;集合只能存储对象。
  • 数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据结构。
3、集合容器多的原因
每个集合容器对数据结构的存储方式都不同。这个存储方式称之为:数据结构。
4、集合框架的构成及分类

5、java中的集合类主要有两个接口派生:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。6、常用集合类之间的层次、继承关系

Collection

        |--List:有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。

                  |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删稍慢。
                  |--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。

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

        |--Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。

                  |--HashSet:底层数据结构是哈希表。HashSet通过hashCode和equals判断元素是否重复。

                  |--TreeSet:可以对Set集合中的元素进行排序,底层数据结构是二叉树。它保证元素唯一性的依据是                    compareTo方法的返回值。

Map

        |--HashMap:底层数据结构是哈希表。HashMap通过hashCode和equals判断元素是否重复。

        |--TreeMap:可以对Map集合中的元素进行排序,底层数据结构是二叉树。它保证元素唯一性的依据是                     compareTo方法的return。

二、Collection类
1、Collection的常见方法:
添加:
boolean add(Object obj);
boolean addAll(Collection coll)
删除:
boolean remove(object obj);
boolean removeAll(Collection coll);
void clear()
判断:
boolean contains(object obj);
boolean containsAll(Colllection coll);
boolean isEmpty():判断集合中是否有元素。
获取:
int size():
Iterator iterator():取出元素的方式:迭代器。
三、List类
1、List特有的常见方法:有一个共性特点就是可以操作角标
添加

void add(index,element);
void add(index,collection);

删除

Object remove(index);

修改

Object set(index,element);

获取

Object get(index);

int indexOf(object);
int lastIndexOf(object);
List subList(from,to);

2、LinkdeList的特有方法

void addFirst(Object);

void addLast(Object);

3、在ArrayList中使用迭代器读取集合中的每个对象

public class Demo01 {public static void main(String[] args) {List<String> al = new ArrayList<String>();// 创建一个ArrayList集合al.add("lisi01");// 往集合中添加对象al.add("lisi02");al.add("lisi03");al.add("lisi04");al.add("lisi03");System.out.println(al);// 创建一个迭代器Iterator<String> it = al.iterator();while (it.hasNext()) {// 在迭代时循环中next调用一次,就要hasNext判断一次。String str = it.next();System.out.println(str);}}}

运行结果为


4、例子:将自定义对象作为元素存到ArrayList集合中,并去除重复元素。

</pre><pre name="code" class="java">
import java.util.*;    public class ArrayListTest {        public static void main(String[] args) {         ArrayList al=new ArrayList();         al.add("java01");         al.add("java02");         al.add("java03");         al.add("java04");         al.add("java01");         al.add("java02");         /**        * 在迭代时循环中next只能调用一次,就要hasNext判断一次。       Iterator it=al.iterator();       while(it.hasNext())       {           sop(it.next()+"....."+it.next());       }        */         sop(al);         al=singleElement(al);         sop(al);        }        public static ArrayList singleElement(ArrayList al)        {   //定义一个临时容器            ArrayList newal=new ArrayList();                Iterator it=al.iterator();                while(it.hasNext())                {                    Object obj=it.next();                    if(!newal.contains(obj))                    {                        newal.add(obj);                    }                }                return newal;        }        public static void sop(Object obj)        {             System.out.println(obj);        }    }    

四、Set

1、Set接口中的方法和Collection中方法一致的。Set接口取出方式只有一种,迭代器。
2、哈希表的原理:
(1)、对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值 称为哈希值。
(2)、哈希值就是这个元素的位置。
(3)、如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 +1顺延。
(4)、存储哈希值的结构,我们称为哈希表。
(5)、既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。
这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。

3、TreeSet:
用于对Set集合进行元素的指定顺序排序,排序需要依据元素自身具备的比较性。
如果元素不具备比较性,在运行时会发生ClassCastException异常。
所以需要元素实现Comparable接口,强制让元素具备比较性,复写compareTo方法。
依据compareTo方法的返回值,确定元素在TreeSet数据结构中的位置。
TreeSet方法保证元素唯一性的方式:就是参考比较方法的结果是否为0,如果return 0,视为两个对象重复,不存。
4、TreeSet集合排序有两种方式,Comparable和Comparator区别:
(1)、让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法。
(2)、让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将该类对象作为实际参数传递给TreeSet集合的构造函数。
5、TreeSet排序代码演示

(1)、定义一个类,实现Comparable接口,覆盖compareTo方法。

class Student implements Comparable     //该接口强制让学生具备比较性。{private String name;private int age;Student(String name,int age){this.name = name;this.age = age;}public int compareTo(Object obj)   //覆盖compareTo方法{//return 0;if(!(obj instanceof Student))throw new RuntimeException("不是学生对象");Student s = (Student)obj;//System.out.println(this.name+"....compareto....."+s.name);if(this.age>s.age)return 1;if(this.age==s.age)  //年龄相等时就再比较名字。{return this.name.compareTo(s.name);}return -1;/**/}public String getName(){return name;}public int getAge(){return age;}}class TreeSetDemo2 {public static void main(String[] args) {TreeSet ts = new TreeSet();ts.add(new Student("lisi02",22));ts.add(new Student("lisi02",21));ts.add(new Student("lisi007",20));ts.add(new Student("lisi09",19));ts.add(new Student("lisi06",18));ts.add(new Student("lisi06",18));ts.add(new Student("lisi007",29));//ts.add(new Student("lisi007",20));//ts.add(new Student("lisi01",40));Iterator it = ts.iterator();while(it.hasNext()){Student stu = (Student)it.next();System.out.println(stu.getName()+"..."+stu.getAge());}}}
(2)、定义一个实现了Comparator接口的比较器,并覆盖compare方法。

class Student {private String name;private int age;Student(String name,int age){this.name = name;this.age = age;}public String getName(){return name;}public int getAge(){return age;}}class TreeSetDemo2 {public static void main(String[] args) {TreeSet ts = new TreeSet();ts.add(new Student("lisi02",22));ts.add(new Student("lisi02",21));ts.add(new Student("lisi007",20));ts.add(new Student("lisi09",19));ts.add(new Student("lisi06",18));ts.add(new Student("lisi06",18));ts.add(new Student("lisi007",29));//ts.add(new Student("lisi007",20));//ts.add(new Student("lisi01",40));Iterator it = ts.iterator();while(it.hasNext()){Student stu = (Student)it.next();System.out.println(stu.getName()+"..."+stu.getAge());}}}class MyCompare implements Comparator   //定义比较器。{public int compare(Object o1,Object o2){Student s1 = (Student)o1;Student s2 = (Student)o2;int num = s1.getName().compareTo(s2.getName());if(num==0) //姓名相同时再比较年龄。{return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));/*if(s1.getAge()>s2.getAge())return 1;if(s1.getAge()==s2.getAge())return 0;return -1;*/}return num;}}

五、泛型

1、定义:jdk1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制
2、特点:
(1)、提高了程序的安全性。
(2)、将运行期遇到的问题转移到了编译期。
(3)、省去了类型强转的麻烦。
(4)、泛型类的出现优化了程序设计。
3、代码演示
public class GenericDemo3 {      public static void main(String[] args) {      Utils<Worker> u=new Utils<Worker>();      u.setObject(new Worker());      Worker w=u.getObject();          /*Tool t=new Tool();         t.setObject(new Worker());         Worker w=(Worker)t.getObject();         */      }  }  class Worker  {  }  class Student3  {  }  //泛型前做法  //什么时候定义泛型类?  //当类中要操作的引用数据类型不确定的时候,早期定义object来完成扩展  //现在定义泛型来完成扩展  class Tool  {  private Object obj;     public void setObject(Object obj)     {         this.obj=obj;     }     public Object getObject()     {         return obj;     }  }  //泛型类。  class Utils<QQ>  {      private QQ q;      public void setObject(QQ q)      {          this.q=q;      }      public QQ getObject()      {          return q;      }  }  /** class Tool {  private worker w;    public void setWorker(worker w)    {        this.w=w;    }    public worker getWorker()    {        return w;    } } */  

六、Map

1、Map集合:该集合存储键值对,一对一对往里存,而且保证键的唯一性。双列集合。
2、Map类常用方法
添加
put(key,value):当存储的键相同时,新的值会替换老的值,并将老值返回。如果键没有重复,返回null。
void putAll(Map);

删除
void clear():清空
value remove(key) :删除指定键。

判断
boolean isEmpty():
boolean containsKey(key):是否包含key
boolean containsValue(value) :是否包含value

取出
int size():返回长度
value get(key) :通过指定键获取对应的值。如果返回null,可以判断该键不存在。当然有特殊情况,就是在hashmap集合中,是可以存储null键null值的。
Collection values():获取map集合中的所有的值。
3、Map与Collection的区别
(1)、Map与Collection在集合框架中属并列存在
(2)、Map存储的是键值对
(3)、Map存储元素使用put方法,Collection使用add方法
(4)、Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素
(5)Map集合中键要保证唯一性
4、Map的两种取出方式
(1)、将map集合中的键都取出存放到set集合中。对set集合进行迭代。迭代完成,再通过get方法对获取到的键进行值的获取。
     Set keySet = map.keySet();     Iterator it = keySet.iterator();     while(it.hasNext()) {         Object key = it.next();         Object value = map.get(key);         System.out.println(key+":"+value);     }
(2)、将map集合中的映射关系存入到了set集合中,而这个集合的数据类型就是:Map.Entry
Set entrySet = map.entrySet();          Iterator it = entrySet.iterator();          while(it.hasNext()) {              Map.Entry  me = (Map.Entry)it.next();              System.out.println(me.getKey()+"::::"+me.getValue());          }  
七、集合框架中的工具类
1、Collections
  • 对集合进行查找
  • 取出集合中的最大值,最小值
  • 对List集合进行排序
2、Arrays
  • 将数组转成List集合
  • 对数组进行排序
  • 对数组进行二分查找对List集合进行排序

八、增强for循环

1、格式:格式: 增强for循环括号里写两个参数,第一个是声明一个变量,第二个就是需要迭代的容器
for( 元素类型 变量名 : Collection集合 & 数组 ) {

}
代码演示:
String [] arr = ["df","de","eg","yh"];//数组的静态定义方式,只试用于数组首次定义的时候for(String s : arr) {   System.out.println(s); }
2、增强for循环和传统for循环的区别:
增强for循环在使用时,必须要明确被遍历的目标。这个目标,可以是Collection集合或者数组,如果遍历Collection集合,在遍历过程中还需要对元素进行操作,比如删除,需要使用迭代器
如果遍历数组,还需要对数组元素进行操作,建议用传统for循环因为可以定义角标通过角标操作元素。如果只为遍历获取,可以简化成高级for循环,它的出现为了简化书写。

九、小结

集合框架是java开发过程中常用到的存储方式,非常重要。Liist中常用的是ArrayList,Set中常用到的TreeSet。Map接口是存放一组key--value的数据的容器,其中每个实例都是一个Map.Entry,Map常用子类有HashMap。在平常的开发中,要读取集合中元素,不需要用迭代器,用增强for比较简便。



0 0
原创粉丝点击