java集合

来源:互联网 发布:招淘宝创业合作伙伴 编辑:程序博客网 时间:2024/05/16 06:29



集合框架: (注:因为对java基础比较熟,所以一些简单的增删改查就不多介绍了)
|--Collection
    |--List :元素是有序的,元素可以重复,因为该集合体系有索引。
        |--ArrayList :底层的数据结构使用的是数组结构,特点:查询速度很快,但是增删稍慢,元素越多越明显。线程不同步。
        |--LinkedList :底层使用的链表数据结构。特点:增删速度很快,查询速度稍慢。
        |--Vector :底层是数组数据结构。线程同步,被ArrayList替代了。
    |--Set :元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
        |--HashSet :数据结构式哈希表,线程时非同步的。
        |--TreeSet :可以对Set集合中的元素进行排序。
    对象时用来存储数据的,集合是用来存储对象引用(地址)
    卫生么会出现这个多的容器呢?
        因为每一个容器对数据的存储方式有不同。这个存储方式称之为:数据结构。
List :接口
      List 集合判断元素是否相同,依据的是元素的equals方法。
        特有方法:凡事可以操作角标的方法都是该体系特有的方法。
      增
        add(index,element);
        addAll(index,Collection);
      删
        remove(index);
      改
        set(index,element);
      查
        get(index);
        subList(from,to);
        listIterator();
      迭代器 Iterator 的使用 
        Iterator it= a1.iterator();
        while(it.hasNest()){
            it.next();//取出的下一个元素
        }
        老外的写法:
        for(Iterator it = a1.iterator(); it.hasNext(); ){
            it.next();
        }
        在迭代时,不可以通过集合对象的方法的操作集合中的元素。
        因为会发生 ConcurrentModificationException 异常

        所以在迭代时,只能用迭代器的方法操作元素,可是 Iterator 方法是有限的,
        只能对元素进行判断,取出,删除的操作。
        如果想要其他的操作,如添加,修改等,就需要使用其子接口 ListIterator
      迭代器 ListIterator 的使用
        ListIterator li= a1.listIterator();
        while(li.hasNest()){
            li.next();//取出的下一个元素,在这里就可以对元素进行修改等操作了,具体查看ListIterator API
        }
        hasPrevious()方法与hasNext()恰恰方法相反,hasPrevious是查看前面是否有元素。
    
  *ArrayList:实现了 List 的子类,使用最为频繁。
    方法:
        a1.retainAll(a2);//a1,a2皆为集合,取交集,a1中只会保留与a2中相同的元素。
        a1.removeAll(a2);//去除交集部分,a1中只会保留a2中不包含的元素。
    去除ArrayList集合中的重复元素,简单小例子
        将老集合的元素顺序向新集合中搬运,每搬运一次都要判断一次,新集合中是否包含当前元素。
        判断用的是contains方法,contains(Object)方法自动调用对象的equals方法。
        remove方法也会自动调用equals方法。通过equals放法来确定两个元素是否相同。
  *LinkedList 
    特有方法:
        addFirst();
        addLast();
        getFirst();
        getLast();
        取出元素,但不删除
        removeFirst();
        removeLast();
        取出元素,并删除。如果集合中没有元素,会出现 NoSuchElementException 异常

        在jdk1.6出现了替代方法
        offerFirst();
        offerLast();
        添加元素
        peekFirst();
        peekLast();
        取出元素,但不删除
        pollFirst();
        pollLast();
        取出元素,并删除。如果集合中没有元素,会返回null
  
  *Vector 
    特有方法:
        //与迭代器方法很像,也是用来取出元素的。
        Enumeration en = v.elements();
        while(en.hasMoreElements()){
            en.nextElement();
        }
Set 
  Set 集合的功能与 List 基本相同
    

  *HashSet 
    HashSet 是如何保证元素的唯一性呢?
        是通过元素的两个方法,hashCodeequals来完成。
        所以一般要存储到HashSet集合中的类对象,都要覆写hashCodeequals方法。
        如果元素的hashCode值相同,才会判断equals是否为true
        如果元素的hashCode值不同,不会调用equals
    注意,对于判断元素是否存在,以及删除等操作,依赖的方法是hashCodeequals方法。
  *TreeSet :可以对Set集合中的元素进行排序,底层数据结构式二叉树。
            保证元素唯一性的依据:compareTo方法return 0,则为相同
    TreeSet排序的两种方式:
    1.TreeSet排序的第一种方式:让类元素具备比较性(称为自然顺序),实现Comparable接口
        //让学生类实现 Comparable接口,使得学生类能够存储到TreeSet集合中去。
        class Student implements Comparable{
            private String name;
            private int age;
            Student(String name, int age){
                this.name = name;
                this.age = age;
            }
            //覆写Comparable接口中的比较方法,首选按照年龄排序
            public int compareTo(Object obj){
                if(!(obj instanceof Student))
                    throw new RuntimeException("不是学生对象");
                Student s = (Student)obj;
                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;
            }
        }
    2.TreeSet排序的第二种方式:让集合自身具备比较性,在集合初始化时,将比较器对象作为参数
            传递给TreeSet集合的构造函数。如果两种比较方式都存在时,以比较器为主。
        //比较器子类,实现Comparator接口,首选按照名字排序
        class MyCompare implements Comparator{
            public int compare(Object o1,Object o2){
                if(!o1 instanceof Student || !o2 instanceof Student)
                    throw new RuntimeException("对象类型不匹配");
                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()));
                }
                return num;
            }
        }
        public static void main(String[] args){
            //在创建TreeSet集合的时候,将比较器传递进去。
            TreeSet ts = new TreeSet(new MyCompare());
        }
-----------------------------------------------
Map :该集合存数键值对,一对一对往里存,而且要保证键的唯一性。
    增删改查crud的方法都比较简单,需要的时候可以查阅API文档。
Map 
    |--Hashtable :底层是哈希表数据结构,不可以存入nullnull值。该集合是线程同步的jdk1.0.效率低
    |--HashMap :底层是哈希表数据结构,允许使用nullnull值。该集合是不同步的。jdk1.2.效率高
    |--TreeMap :底层是二叉树数据结构,线程不同步。可以用于给Map集合中键进行排序。

   *Map 集合的两种取出方式:
    1.keySet:将map中所有的键存入Set集合。因为Set集合具备迭代器。
      所以可以迭代方式取出所有的键,在根据get方法,获取每一个键对应的值。
    2.entrySet:返回此映射中包含的映射关系的 Set 视图。通过Set集合迭代取出映射关系 Map.Entry<k,v>对象。
      通过映射关系对象获得 键,值。
      Map.Entry Map的一个内部接口,HashMap实现了MapHashMap内部类实现了Map.Entry

TreeMap :TreeSet集合很像,其实Set底层就是使用了Map集合。
    put(key,value)方法:添加元素,如果添加时,出现相同的键,那么后添加的值会覆盖原有的键对应的值,
    并且put方法会返回被覆盖的值。

   *练习
    “asdfgshjkl”获取该字符串的字母出现次数。
    希望打印结果:a(1)s(2).....
    当发现有映射关系时,可以选择Map集合。因为map集合中存放的就是映射关系。
   *思路:
   1.将字符串转换成字符数组。因为要对每一个字母进行操作。
   2.定义一个map集合,因为打印结果的字母有书序,所以使用TreeMap集合。
   3.遍历字符数组,将每一个字符作为键去查map集合。
     如果返回null,将该字母和1存入到map集合中。
     如果返回不是null, 说明该字母在map集合已经存在并有对应次数。
     那么就获取该次数并进行自增,然后将该字母和自增后的次数,存入到map集合中。
     覆盖原有的键对应的次数。
------------------------------------------
集合框架工具类:
Collections :专门用于对集合操作的工具类。
   *此方法 public static <T extends Comparable<? super T>> void sort(List<T> list)
    若想进行比较,那么T类必须具备比较性,也就是实现Comparable接口(T extends Comparable)
   *想要对List集合排序,用到了Collections.sort(List<T> list, Comparator<? super T> c)方法。
    此方法可以接收比较器。避免了自定义类不可比较的问题。
   *二分搜索法原理:
    //list集合中查找key的索引值,如果key不存在,则返回key对应的位置*(-1)-1;
    public static int halfSearch(List<String> list,String key){
        int max,min,mid;
        max = list.size()-1;
        min = 0;
        while(min<=max){
            mid = (max+min)>>1 // (max+min)/2;
            String Str = list.get(mid);
            int num = str.compareTo(key);//比较list中间位置的值(str)是否大于key;
            if(num>0)
                max = mid - 1;
            else if(num < 0)
                min = mid + 1;
            else return mid;//如果查到结果则返回相应的索引
        }
        return -min-1;//经循环,找到不key,则返回key对应的位置*-1-1
    }
   *反转集合:
   *Collections.reverse(list) :list集合的原有顺序反转
   *Collections.reverseOrder() :返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。 
   *Collections.reverseOrder(Comparator<T> cmp) :返回一个比较器,它强行逆转指定比较器的顺序。 
   *同步集合方法: Collections 提供方法对多线程不同步的集合进行加锁处理,并返回一个线程同步的集合。
   *swap(List<?> list, int i, int j) :在指定列表的指定位置处交换元素。
   *shuffle(List<?> list) :使用默认随机源对指定列表进行置换。
------------------------------------------
Arrays :数组操作工具类
   *Arrays.asList(arr) ://arr数组转换成list集合。
    注意:将数组变成集合,不可以使用集合的增删方法。因为数组的长度是固定的。
    如果增删,那么会发生 UnsupportedOperationException
    如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。
    如果数组中的元素都是i基本数据类型,那么会将该数组作为集合中的元素存在。
   *ArrayList 中也有将集合转为数组的方法。toArray
    将集合转为数组的意义:为了限定对元素的操作,集合可以对集合的内容进行增删等,但数组只可以查阅等操作。


原创粉丝点击