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)之间的随机数。

原文地址:https://www.cnblogs.com/zengming/p/7483381.html