zoukankan      html  css  js  c++  java
  • Java基础知识_毕向东_Java基础视频教程笔记(14-18集合框架)

      14天-01-集合框架
    集合类出现:面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
    数组与集合类同是容器,有何不同?
    数组长度是固定的,集合长度是可变的;数组中只可以存储基本数据类型,集合可以存储对象。

    迭代器其实就是集合的取出元素的方式,用于循环遍历

      集合迭代器Iterator:
    在集合中,把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素。那么取出方式就被定义成了内部类。而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容,判断和取出,那么就将这些共性抽取,这个就是Iterator,对外提供iterator();方法,hasNext();判断是否还有元素,next();获取下一个元素,remove();移除此元素。

      Collection 接口    add,remove,contains,clear,iterator


    List: 元素是有序的,元素可以重复,因为该集合体系有索引。
      ArrayList:底层使用的是数组数据结构。特点:查询、修改操作很快,增加、删除慢。线程非同步
      LinkList:底层使用的是链表数据结构。特点:增加、删除、修改操作快,查询慢
      Vector:底层使用的是数组数据结构。特点:线程同步,被ArrayList代替了
    Set: 元素是无序的(存入和取出的顺序不一致),元素不可以重复。
      HashSet:底层使用的是哈希表数据结构。线程非同步。保证元素唯一性的原理:判断元素的hashCode值是否相同,如果相同,还会继续判断元素的equals方法。
      TreeSet:底层使用的是二叉树数据结构。保证元素唯一性的原理:比较compareTo方法return -1,0,1。可以对Set集合中的元素排序。

      List:特有方法,凡是可以操作角标的方法都是该体系特有的方法。
    增   add(index,element);   addAll(index,Collection);
    删   remove(index);
    改   set(index,element);
    查   get(index); subList(from,to);   //包括开始,不包括结束元素 listIterator();

    Listiterator:该接口只能通过List集合的listIterator()方法获取。
    List集合特有的迭代器,ListIterator是Iterator的子接口。
      在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModifyException异常。所以,在迭代器时,只能用迭代器的删取操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。如果想要其他操作如添加,修改等,就需使用其子接口:ListIterator

      Vector:
    枚举就是Vector特有的取出方式,其实枚举和迭代器是一样的,因为枚举的名称以及方法名称都过长,所以被迭代器取代了。Enumeration<E> elements()获取Vector枚举元素类似Iterator,hasMoreElements();//判断是否有下一个元素    nextElement();//获取下一个元素

      LinkedList:
    LinkedList特有方法:
    addFirst();    addLast(); //添加元素
    getFirst();    getLast(); //获取元素,不删除元素
    removeFirst();   removeLast(); //删除元素,并获取元素。如果集合中没有元素,会出现NoSuchElementException
    在JDK1.6出现了替代方法:
    offerFirst();   offerLast(); //添加元素
    peekFirst();   peekLast(); //获取元素,不删除元素。如果集合中没有元素,会返回null
    pollFirst();   pollLast(); //删除元素,并获取元素。如果集合中没有元素,会返回null

    List集合判断元素是否相同,依据元素的equals方法。

     1 /*
     2 使用LinkedList模拟一个堆栈和队列数据结构
     3 堆栈:先进后出。队列:先进先出。
     4 */
     5 //队列:先进先出
     6 class Queue
     7 {
     8     private LinkedList link;
     9 
    10     Queue()
    11     {
    12         link = new LinkedList();
    13     }
    14 
    15     public void add(Object object)
    16     {
    17         link.addFirst(object);
    18     }
    19 
    20     public Object get()
    21     {
    22         return link.removeLast();
    23     }
    24 
    25     public boolean isEmpty()
    26     {
    27         return link.isEmpty();
    28     }
    29 }
    30 //堆栈:先进后出
    31 class Stack
    32 {
    33     private LinkedList link;
    34 
    35     Stack()
    36     {
    37         link = new LinkedList();
    38     }
    39 
    40     public void add(Object object)
    41     {
    42         link.addFirst(object);
    43     }
    44 
    45     public Object get()
    46     {
    47         return link.removeFirst();
    48     }
    49 
    50     public boolean isEmpty()
    51     {
    52         return link.isEmpty();
    53     }
    54 }
    LinkedList模拟一个堆栈和队列数据结构

      HashSet:

    HashSet是如何保证元素唯一性的?
      是通过元素的两个方法,hashCode和equals来完成。如果元素的hashCode值相同,才会判断equals是否为true;如果元素的hashCode值不同,不会调用equals。
    注意:对于HashSet判断元素是否存在,以及添加,删除等操作,依赖的方法是元素的hashCodeequals方法,如果添加操作判断元素已经存在,则丢弃要添加的元素。List判断元素是否相同是用equals方法

      注:排序时,当主要条件相同时,一定要判断一下次要条件。
      TreeSet: 比较compareTo方法return -1,0,1,-1是比自身小,0是相同,1是比自身大。
    TreeSet排序的第一种方式,是让元素自身具备比较性,元素需要实现Comparabel接口,覆盖compareTo方法。这种方式也成为元素的自然顺序或者叫做默认顺序。
    TreeSet排序的第二种方式,当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。在集合初始化时,就传入特定比较方式的比较器。当两种排序方式都存在时,以比较器为主
    TreeSet存储自定义对象示例:

     1 import java.util.*;
     2 /*
     3 需求:往TreeSet集合中存储自定义对象Person,并按照Person的age进行排序。
     4 */
     5 class Demo
     6 {
     7     public static void main(String[] args)
     8     {
     9         TreeSet array = new TreeSet();
    10         array.add(new Person("test2", 12));
    11         array.add(new Person("test4", 14));
    12         array.add(new Person("test1", 11));
    13         array.add(new Person("test4", 16));
    14         array.add(new Person("test3", 13));
    15         Iterator it = array.iterator();
    16         while (it.hasNext())
    17         {
    18             Object temp = it.next();
    19             Person p = (Person) temp;
    20             sop("array element is " + p.name + "  " + p.age);
    21         }
    22         sop("********Game over******");
    23     }
    24 
    25     public static void sop(Object obj)
    26     {
    27         System.out.println(obj);
    28     }
    29 }
    30 //Comparable该接口强制要求实现比较方式
    31 class Person implements Comparable
    32 {
    33     public String name;
    34     public int age;
    35 
    36     Person(String name, int age)
    37     {
    38         this.name = name;
    39         this.age = age;
    40     }
    41 
    42     public int compareTo(Object obj)
    43     {
    44         if (!(obj instanceof Person))
    45         {
    46             throw new RuntimeException(obj + " is not a Person Object");
    47         }
    48         Person p = (Person) obj;
    49         if (this.age > p.age)
    50         {
    51             return 1;
    52         }
    53         if (this.age == p.age)
    54         {
    55             return this.name.compareTo(p.name);
    56         }
    57         return -1;
    58     }
    59 }
    TreeSet存储自定义对象

      15天-06-集合框架-泛型

      泛型:即“参数化类型”,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。JDK1.5版本出现的新特性,用于解决安全问题,是一个类型安全机制。
      好处:1.将运行时期出现的问题ClassCastException转移到了编译时期。方便于程序员解决问题,让运行时问题更少,更安全。
         2.避免了强制转换。
    泛型格式:通过<>来定义要操作的引用数据类型。
    在使用java提供的对象时,什么时候使用泛型?
      通常在集合框架中很常见,只要见到<>就可以使用泛型。其实<>就是用来接收类型的,当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
      泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了
      泛型方法定义的泛型,在整个方法中有效。如果不同方法操作不同类型,可以将泛型定义在方法上
    注:静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上
    泛型的限定:?通配符,也可以理解为占位符。
      <? extends T>: 可以接收T类型或者T的子类型,上限;
      <? super E>: 可以接收E类型或者E的父类型,下限。

      16天-01-集合Map
    Map HashTable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。
    HashMap:底层是哈希表数据结构,允许使用null键null值,该集合是线程非同步的。JDK1.2,效率高。
    TreeMap:底层是二叉树数据结构,线程不同步,可以用于给map集合中的键进行排序
    注:Map和Set很像,其实Set底层使用的就是Map集合

    Map集合:该集合存储键值对,一对一对存储,而且要保证键的唯一性
    Map集合的取出原理:将map集合转成Set集合,再通过迭代器取出。
    1.添加   putAll(Map<? extends K,? extends V> m)
    put(K key,V value);//添加元素,添加时如果出现相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。如果没有相同的键,put方法返回null。
    2.删除  clear();   remove();
    3.判断  containsValue(Object);   containsKey(Object key);   isEmpty();
    4.获取  get(Object key);  //获取值     size();//获取Map集合键数量   values();//获取Map集合值集合
      keySet();将map中所有的键存入到Set集合中,因为Set集合具备迭代器。以迭代方式取出所有的键,再根据get方法获取每一个键对应的值。
      Set<Map.Entry<k,v>> entrySet(); 将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry,再通过Map.Entry中getKey和getValue获取键和值。

    Map.Entry:其实Entry也是一个接口,它是Map接口中的一个内部static接口。

    TreeMap获取字符串中字母出现的次数:

     1 import java.util.*;
     2 /*
     3 需求:"fghjdadadlfczcdadfaf"获取该字符串中的字母出现的次数。打印:a(4),c(2)...
     4 */
     5 class Demo{
     6     public static void main(String[] args)
     7     {        
     8         //原始字符串
     9         String sourceString = "fghjdadadlfczcdadfaf";
    10         char[] chs = sourceString.toCharArray();
    11         TreeMap<Character, Integer> result = new TreeMap<Character, Integer>();
    12         int length = chs.length;
    13         for (int i = 0; i < length; i++)
    14         {
    15             char ch = chs[i];
    16             int temp = 0;
    17             boolean flag = (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
    18             if (!flag)
    19             {
    20                 continue;
    21             }
    22             Integer value = result.get(ch);
    23             if (value != null)
    24             {
    25                 temp = value;
    26             }
    27             value = value == null ? 1 : 1 + value;
    28             result.put(ch, value);
    29         }
    30         sop("source string is: " + sourceString);
    31         StringBuilder showResult = new StringBuilder();
    32         for (Iterator<Map.Entry<Character, Integer>> it = result.entrySet().iterator(); it.hasNext(); )
    33         {
    34             Map.Entry<Character, Integer> temp = it.next();
    35             showResult.append(temp.getKey() + "(" + temp.getValue() + ") ");
    36         }
    37         sop("char statistics result:" + showResult);
    38         sop("********Game over******");
    39     }
    40     
    41     private static void sop(Object obj)
    42     {
    43         System.out.println(obj);
    44     }
    45 }
    TreeMap获取字符串中字母出现的次数

      集合框架的工具类:主要提供对集合常用操作,里面都是静态方法。

      Collections
    static <T> List<T> synchronizedList(List<T> list);  //创建一个同步List集合对象,底层加锁调用List方法
    static void shuffle(List<?> list);  //随机排序集合

      Arrays:用于操作数组的工具类。排序,查找,反转
    asList:将数组变成List集合。优点:可以使用集合的思想和方法来操作数组中的元素。
    注:将数组变成集合,不可以使用集合的增删方法,因为数组的长度是固定的。否则有UnsupportedOperationException
      如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。
      如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的一个元素存在。
    ArrayList转成数组:<T> T[] toArray(T[] a);
    当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。
    当指定类型的数组长度大于了集合的size,就不会新创建数组,而是使用传递进来的数组。所以创建一个大小是size的数组最优。
    为什么要将集合变成数组? 为了限定对元素的操作,不需要进行增删了。

      高级for循环:格式 for(数据类型 变量 ; 被遍历的集合(Collection)或者数组){    }
      对集合进行遍历,只能获取集合元素,但是不能对集合进行操作。
      迭代器除了遍历,还可以进行remove操作集合中的元素。
      如果是用ListIterator,还可以在遍历过程中进行增删改查的操作。
    传统for与高级for有什么区别?
    高级for有一个局限性,必须有被遍历的目标。
    建议在遍历数组的时候,还是用传统for,因为传统for可以定义脚标。

      JDK1.5版本新特性
      可变参数:(形参类型... param)其实就是一种数组参数的简写形式,不用每一次都手动的建立数组对象,只要将要操作的元素作为参数传递即可,隐式将这些参数封装成了数组。
    注:在使用可变参数时,可变参数一定要定义在参数列表最后面。
      静态导入(StaticImport): import static java.lang.System.*; //导入System类中的所有静态成员。
    当类名重名时,需要指定具体的包名。当方法重名时,需要指定具体所属的对象或者类。

      18天-01-其他对象System类:描述系统的一些信息。System类中的方法和属性都是静态的。
    PrintStream out:标准输出,默认是控制台
    InputStream in:标准输入,默认是键盘
    String getProperty(String key);//获取系统属性信息
    String setProperty(String key, String value);//设置系统属性

      18天-02-其他对象Runtime类:每个Java应用程序都有一个Runtime类的实例,是应用程序与运行应用程序的环境进行交互的接口
    该类并没有提供构造函数,说明不可以new对象,那么会直接想到该类中的方法都是静态的。发现该类中还有非静态方法,说明该类肯定会提供方法获取本类对象,而且该方法是静态的并且返回值类型是本类类型。由此特点可以看出该类使用了单例设计模式完成。
    Runtime getRuntime();获取Runtime类。
    Process exec(String command);执行命令,返回一个Process进程,可用于启动外部程序

      18天-03-其他对象Date类:表示特定的瞬间,精确到毫秒。
    SimpleDateFormat类是Date的格式化类,调用format(Date date)方法格式化指定的Date对象。

      18天-04-其他对象Calendar类:用于替换Date类,操作日期
    static int DAY_OF_MONTH; 月中的天数
    static int DAY_OF_WEEK; 周中的天数
    calendar.set(year,2,1); //某一年的3月1日
    calendar.add(Calendar.DAY_OF_MONTH,-1);//3月1日向前推一天就是2月最后一天。

      18天-05-其他对象Math-Random类
    static double abs(double a);//求一个数字的绝对值
    static double ceil(double a);//求大于一个数字的最小整数,向上取整。
    static double floor(double a);//求小于一个数字的最大整数,向下取整。
    static long round(double a);//求一个小数四舍五入的整数。
    static double pow(double a, double b);//求a的b次幂,求幂。
    static double random();//随机数,返回带正号的double值,[0,1)
    Random r=new Random();r.nextInt(10)+1;//获取一个[1~10)之间的随机数。

  • 相关阅读:
    【python进阶】哈希算法(Hash)
    【数据库】MongoDB操作命令
    【数据库】MongoDB安装&配置
    【python基础】元组方法汇总
    【python基础】集合方法汇总
    滴水穿石-04Eclipse中常用的快捷键
    滴水穿石-03一道面试题引发的思考
    滴水穿石-02制作说明文档
    滴水穿石-01JAVA和C#的区别
    步步为营101-同一个PCode下重复的OrderNumber重新排序
  • 原文地址:https://www.cnblogs.com/zengming/p/7483381.html
Copyright © 2011-2022 走看看