• 集合类和泛型


    一、集合类

    集合类和数组同是容器,有何不同?

    1.数组的长度是固定的,集合类的长度不固定

    2.数组存储基本类型,集合类存储对象,集合中不能存基本数据类型。

    集合容器因为内部数据结构不同,有多种具体容器。

    不断向上抽取,就形成了集合框架。

    框架的顶层为Collection接口。

     (一)LIst

    有序的Collection,此处有序是指数据存入的顺序。

    特点:

    1.有序,存入和取出的顺序一致

    2.所有元素有角标(素引)

    LIst常见的特有方法有一个共同的特点,就是可以操作角标。

    List list=new ArrayList();
    list.add("a1");
    list.add("a2");
    Iterator it=list.Iterator();
    while(it.hasNext())
    {
        Object obj=it.Next();
        if (obj.equals("a2"))
       {
            list.add("a3"); 
        }
    }

    上述代码在执行时是错误的,因为List类的迭代器在使用时容器长度是固定的,不能在迭代时修改容器的长度。

    要修改上述错误,我们不能在迭代时修改容器的长度,但是我们可以修改迭代器的长度。可以使用Iterator接口的子接口ListIterator来实现。代码如下:

    List list=new ArrayList();
    list.add("a1");
    list.add("a2");
    Iterator it=list.listIterator(); //使用列表迭代器
    while(it.hasNext())
    {
        Object obj=it.Next();
        if (obj.equals("a2"))
       {
           it.add("a3");  //使用迭代器的插入方法
        }
    }

    List接口的有三种:(一般除了Vector外,都是不同步的。)

    1.Vector:内部结构是数组数据结构,容量会自动调整。Vector是同步的。

    2.ArrayList:内部也是数组数据结构,基本等同于Vector,但是它是不同步的,单线程中效率较高。查询的速度快。

    3.LinkedList:内部是链表数据结构,是不同步的,增删速度非常快。

    (二)Set

    特点:

    1.所有元素不重复

    2.没有顺序

     主要有两种结构:

    1.HashSet:无重复,无顺序

    判断两个对象是否相同,先判断两个对象的HashCode,如相同,再判断equals,如相同,则两个对象相同。如HashCode不相同,则无须再判断equals。

    2.TreeSet:无重复,有顺序

    (三)Map

    Collection一次添加一个元素,Map一次添加一对元素。所以Map也叫双列集合,Map集合中存储的是键值对。一个映射中不能包含重复的键,每个键只能对应一个值。也就是说Map必须保证键的唯一性。

    1.Map添加:

      value put(key,value):返回前一个和key关联的值,如果没有,返回null

    2.删除

    void clear():清空map集合

    value remove(key):根据指定的key翻出对应的键值对

    3.判断

    boolean containsKey(key);

    boolean containsValue(value);

    boolean isEmpty();

    4.获取

    value get(key):通过键获取值,如果没有该键,返回null。当然可以通过返回null,来判断是否包含指定键。

    int size(); 获取键值对的个数

     Map集合没有迭代器。通过Map转成set就可以迭代。找到了另一个方法entrySet。该方法将键和值的映射关系作为对象存储到了set集合中,而这个映射关系的类型就是Map.Entry类型。

    Set<Map.Entry<Integer,String>> entrySet=map.entrySet();
    Iterator<Map.Entry<Integer,String>> it=entrySet.iterator();
    while (it.hasNext())
    {
         Map.Entry<Integer,String> me=it.next();
        Integer key=me.getKey();
        String value=me.getValue();
        System.out.println(key+":"+value);
    }

     Map常用的子类:

    1.Hasthtable:内部结构是哈希表,是同步的,不允许null作为键和null作为值

         有一个子类:properties,用来存储键值对型的配置文件的信息。经常和IO技术相结合。

    2.HashMap:内部结构是哈希表,是不同步的,允许null作为键和null作为值

    3.TreeMap:内部结构是二叉树,是不同步的,可以对Map集合中的键进行排序。

     二、泛型

    在JDK1.5以后出现。

    好处:

      1.将运行时期的问题ClassCastException转到了编译时期。

      2.避免了强制转换的麻烦。

    <>:什么时候用?当操作的引用数据类型不确定的时候,就使用<>。将要操作的引用数据类型引入即可。其实<>就是一个用于接收具体引用数据类型的参数范围。

    运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。

    定义一个泛型类:

    pulbic class Tool<w>

    {

        ……

    }

    也可以定义一个泛型接口

    interface Inter<T>

    {

       public void show(T t)

      { }

    }

     可以将泛型定义在方法上:

    public <w> void show(w str)

    {

         ……

    }

    当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型,只能将泛型定义在方法上。

    public static <w> void show(w str)

    {

        ……

    }

    在使用泛型参数时,如果有多种泛型,可使用如下代码:

    public void show(Tool<?> t)

    {

         Iterator <?> it=t.iterator();  

      ……

    }

    或用如下代码:

    public <T> void show(Tool<T> t)

    {

         Iterator <T> it=t.iterator();  

      ……

    }

    泛型通配符还可以进行限定,如向上限定(一般用于存储数据):

    public static void show(Tool<? extends Person> str)

    {

        ……

    }

    也可向下限定(一般用于读取数据):

    public static void show(Tool<? super Person> str)

    {

        ……

    }

    最后,集合的一些技巧:

    需要唯一吗?

    需要:Set

       需要制定顺序:

                     需要:TreeSet

                    不需要:HashSet

    不需要:List

           需要频繁增删吗?

                    需要:LinkedList

                    不需要:ArrayList

    Array——数组、查询快、有角标

    Link——链表、增删快、add/get/remove/first/lash等方法

    Hash——哈希表、唯一性,有时需要覆盖hashCode和equals方法

    Tree——二叉树、排序,两个接口:Comparable和Comparator

    三、集合工具

    1. Collections

        里面的方法都是静态的。比如排序:

    public static void  show()
    {
        List<String> list=new ArrayList<String>();
        list.add("abcde");
        list.add("cba");
        list.add("aa");
        list.add("zzz");
        Collections.sort(list);
        System.out.println(list);
    }

      比如交换值:

       Collections.swap(list,i,j);

     对集合中的位置进行随机

      Collections.shuffle(list);

    给非同步的集合加锁,可以使用Collections.synchronizedCollection(Collection<T> c),其原理如下 :

    List list=new ArrayList(); //非同步
    list=MyCollections.synList(list); //返回一个同步的list
    
    
    class MyCollections
    {
       public List synList(List list)
       {
           return new MyList(list);
       }
    
       private class MyList implements List
       {
           private List list;
           private static final Object lock=new Object();
           MyList(List list)
           {
               this.list=list;
           }
    
           public boolean add(Object obj)
           {
               synchronized(lock)
               {
                   return list.add(obj);
               }
           }
    
           public boolean remove(Object obj)
           {
               synchronized(lock)
               {
                   return list.remove(obj);
               }
           }
       }
    
    }

    2.Arrays

    将数组转成集合

    int [] arr={31,11,51,61};

    List<int []> list=Arrays.asList(arr);

    将集合转数组

    List <String> list=new ArrayList<String>();
    list.add("abc1");
    list.add("abc2");
    list.add("abc3");
    /*toArray需要传定一个指定类型的数组,如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同的size的数组,如果长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位默认为null
    */
    string[] arr=list.toArray(new String[2]);
    System.out.println(Arrays.toString(arr));

     注意,导入静态名称空间时,要用

    import static java.util.Collections.sort;

  • 相关阅读:
    Hashtable源码分析
    ConcurrentHashMap1.7源码分析
    JDK1.8新特性
    回炉Spring--Bean生命周期及AOP
    @DateTimeFormat 和 @JsonFormat 注解
    面向切面编程-日志切面应用及MDC使用
    maven 多模块开发
    maven 安装
    ztree树节点重叠问题
    Java问题解读系列之IO相关---Java深拷贝和浅拷贝
  • 原文地址:https://www.cnblogs.com/jsddj/p/7641346.html
Copyright © 2020-2023  润新知