集合概述
当需要在Java程序中记录单个数据内容时,则声明一个变量。 
当需要在Java程序中记录多个类型相同的数据内容时,声明一个一维数组。 
当需要在Java程序中记录多个类型不同的数据内容时,则创建一个对象。 
当需要在Java程序中记录多个类型相同的对象数据时,创建一个对象数组。 
当需要在Java程序中记录多个类型不同的对象数据时,则准备一个集合。
集合的框架结构
集合的框架结构 Java中集合框架顶层框架是:java.util.Collection集合 和 java.util.Map集合。 
其中Collection集合中存取元素的基本单位是:单个元素。 
其中Map集合中存取元素的基本单位是:单对元素。
Collection集合
java.util.Collection接口是List接口、Queue 接口以及Set接口的父接口,因此该接口里定义的方法 既可用于操作List集合,也可用于操作Queue集合和Set集合。
常用的方法
方法如下:
public boolean add(E e):  把给定的对象添加到当前集合中 。
 
public void clear() :清空集合中所有的元素。
 
public boolean remove(E e): 把给定的对象在当前集合中删除。
 
public boolean contains(E e): 判断当前集合中是否包含给定的对象。
 
public boolean isEmpty(): 判断当前集合是否为空。
 
public int size(): 返回集合中元素的个数。
 
public Object[] toArray(): 把集合中的元素,存储到数组中。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   | public static void main(String[] args) {                           Collection<String> coll = new ArrayList<String>();                           coll.add("小李广");         coll.add("扫地僧");         coll.add("石破天");         System.out.println(coll);                  System.out.println("判断 扫地僧 是否在集合中"+coll.contains("扫地僧"));                  System.out.println("删除石破天:"+coll.remove("石破天"));         System.out.println("操作之后集合中元素:"+coll);                  System.out.println("集合中有"+coll.size()+"个元素");                  Object[] objects = coll.toArray();                  for (int i = 0; i < objects.length; i++) {             System.out.println(objects[i]);         }                  coll.clear();         System.out.println("集合中内容为:"+coll);                  System.out.println(coll.isEmpty());
  }
  | 
 
Iterator接口
java.util.Iterator接口主要用于描述迭代器对象,可以遍历Collection集合中的所有元素。 java.util.Collection接口继承Iterator接口,因此所有实现Collection接口的实现类都可以使用该迭代器对象。
| 方法声明 | 
功能介绍 | 
| boolean hasNext() | 
判断集合中是否有可以迭代/访问的元素 | 
| E next() | 
用于取出一个元素并指向下一个元素 | 
| void remove() | 
用于删除访问到的最后一个元素 | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | public static void main(String[] args) {            Collection c1 = new ArrayList();      c1.add("one");      c1.add(2);      c1.add(new Person("zhangfei", 30));      System.out.println("c1 = " + c1);            System.out.println("-----------------------------");                  Iterator iterator1 = c1.iterator();      System.out.println(iterator1.hasNext());       System.out.println("获取到的元素是:" + iterator1.next());      System.out.println(iterator1.hasNext());      System.out.println("获取到的元素是:" + iterator1.next());      System.out.println(iterator1.hasNext());      System.out.println("获取到的元素是:" + iterator1.next());            System.out.println(iterator1.hasNext());            System.out.println("获取到的元素是:" + iterator1.next());      while(iterator1.hasNext()){          System.out.println("获取到的元素是:" + iterator1.next());      } }
  | 
 
遍历集合
1 2 3 4 5 6 7 8 9 10 11
   | public static void main(String[] args) {     Collection<String> coll = new ArrayList<String>();     coll.add("hd");     coll.add("jc");     coll.add("wyb");          for(String s :coll){                  System.out.println(s);     } }
  | 
 
List集合
基本概念
java.util.List集合是Collection集合的子集合,该集合中允许有重复的元素并且有先后放入次序。 
该集合的主要实现类有:ArrayList类、LinkedList类、Stack类、Vector类。 
其中ArrayList类的底层是采用动态数组进行数据管理的,支持下标访问,增删元素不方便。 
其中LinkedList类的底层是采用双向链表进行数据管理的,访问不方便,增删元素方便。
ArrayList 更适合于随 机访问而LinkedList更适合于插入和删除;在性能要求不是特别苛刻的情形下可以忽略这个差别。 
其中Stack类的底层是采用动态数组进行数据管理的,该类主要用于描述一种具有后进先出特征的 数据结构,叫做栈(last in first out LIFO)。
其中Vector类的底层是采用动态数组进行数据管理的,该类与ArrayList类相比属于线程安全的 类,效率比较低,以后开发中基本不用。
常用方法
List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,如下:
public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
 
public E get(int index):返回集合中指定位置的元素。
 
public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
 
public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   | public static void main(String[] args){          List<String> list = new ArrayList<String>();          list.add("图图");     list.add("小美");     list.add("不高兴");     System.out.println(list);          list.add(1,"没头脑");     System.out.println(list);               System.out.println("删除索引位置为2的元素");     System.out.println(list.remove(2));     System.out.println(list);               list.set(0, "三毛");     System.out.println(list);               for(int i = 0;i<list.size();i++){         System.out.println(list.get(i));     }          for (String string : list) {         System.out.println(string);     } }
  | 
 
List的子类
ArrayList集合
java.util.ArrayList集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。 
LinkedList集合
java.util.LinkedList集合数据存储的结构是链表结构。方便元素添加、删除的集合。 
常用方法
public void addFirst(E e):将指定元素插入此列表的开头。
 
public void addLast(E e):将指定元素添加到此列表的结尾。
 
public E getFirst():返回此列表的第一个元素。
 
public E getLast():返回此列表的最后一个元素。
 
public E removeFirst():移除并返回此列表的第一个元素。
 
public E removeLast():移除并返回此列表的最后一个元素。
 
public E pop():从此列表所表示的堆栈处弹出一个元素。
 
public void push(E e):将元素推入此列表所表示的堆栈。
 
public boolean isEmpty():如果列表不包含元素,则返回true。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | public static void main(String[] args) {     LinkedList<String> link = new LinkedList<String>();          link.addFirst("abc1");     link.addFirst("abc2");     link.addFirst("abc3");     System.out.println(link);          System.out.println(link.getFirst());     System.out.println(link.getLast());          System.out.println(link.removeFirst());     System.out.println(link.removeLast());     while (!link.isEmpty()) {                  System.out.println(link.pop());              }     System.out.println(link); }
  | 
 
Set接口
java.util.Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口不同的是,Set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。
Set集合有多个子类,这里我们介绍其中的java.util.HashSet、java.util.LinkedHashSet这两个集合。 
HashSet集合
底层数据结构是哈希表  
 
存取无序
 
不可以存储重复元素
 
没有索引,不能使用普通for循环遍历
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | public static void main(String[] args) throws Exception {     Student stu1=new Student("令狐冲",19);     Student stu2=new Student("令狐冲",19);     Student stu3=new Student("风清扬",79);     Student stu4=new Student("岳不群",49);     HashSet<Student> set=new HashSet<Student>();     set.add(stu1);     set.add(stu2);     set.add(stu3);     set.add(stu4);     System.out.println(set.contains(stu2));     for(Student stu:set){         System.out.println(stu);     } }
  | 
 
覆盖Student中的equals和hashCode方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | @Override public boolean equals(Object obj){     if(obj instanceof  Student){         Student stu= (Student) obj;         if(stu.age==this.age&&stu.name.equals(this.name)){             return true;         }     }     return false; } @Override public int hashCode(){     return name.hashCode()+age; }
   | 
 
for循环遍历后删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | public static void main(String[] args) {         Student stu1=new Student("吴作成",18);         Student stu2=new Student("杨志超",19);         Student stu3=new Student("商政",21);         Student stu4=new Student("商政",21);         Student stu5=new Student("靳东升",20);         HashSet<Student> set=new HashSet<Student>();         set.add(stu1);         set.add(stu2);         set.add(stu3);         set.add(stu4);         set.add(stu5);         System.out.println(set);         HashSet<Student> setDel=new HashSet<Student>();         for(Student stu:set){             if(stu.name.startsWith("商")){                 setDel.add(stu);             }         }         set.removeAll(setDel);         System.out.println(set);     }
  | 
 
LinkedHashSet
我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢?
在HashSet下面有一个子类java.util.LinkedHashSet,它是链表和哈希表组合的一个数据存储结构。 
1 2 3 4 5 6 7 8 9 10 11
   | public static void main(String[] args) {     Set<String> set = new LinkedHashSet<String>();     set.add("bbb");     set.add("aaa");     set.add("abc");     set.add("bbc");     Iterator<String> it = set.iterator();     while (it.hasNext()){         System.out.println(it.next());     } }
  | 
 
TreeSet集合
 TreeSet集合概述和特点【应用】
TreeSet集合基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   |  Set<String> s1 = new TreeSet<>(); System.out.println("s1 = " + s1);
  boolean b1 = s1.add("aa"); System.out.println("b1 = " + b1); System.out.println("s1 = " + s1); b1 = s1.add("cc"); System.out.println("b1 = " + b1); System.out.println("s1 = " + s1); b1 = s1.add("bb"); System.out.println("b1 = " + b1);
  System.out.println("s1 = " + s1);
 
  | 
 
排序Comparator和Comparable接口
实现Comparable 接口 并重写方法
1 2 3 4 5 6 7 8
   | public class Student implements Comparable<Student>{     @Override     public int compareTo(Student stu) {         if(this.age>stu.age) return -1;         if(this.age<stu.age) return 1;         return 0;     } }
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | public static void main(String[] args) throws Exception {     Student stu1=new Student("令狐冲",19);     Student stu2=new Student("令狐冲",19);     Student stu3=new Student("风清扬",79);     Student stu4=new Student("岳不群",49);     TreeSet<Student> set= new TreeSet<Student>();     set.add(stu1);     set.add(stu2);     set.add(stu3);     set.add(stu4);     System.out.println(set.contains(stu2));     for(Student stu:set){         System.out.println(stu);     } }
  | 
 
实现Comparator接口的比较器
1 2 3 4 5 6 7 8
   | public class StuComptor implements Comparator<Student> {     @Override     public int compare(Student stu1, Student stu2) {         if(stu1.age>stu2.age)return 1;         if(stu1.age<stu2.age)return -1;         return 0;     } }
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | public static void main(String[] args) throws Exception {         Student stu1=new Student("令狐冲",19);     Student stu2=new Student("令狐冲",19);     Student stu3=new Student("风清扬",79);     Student stu4=new Student("岳不群",49);     TreeSet<Student> set= new TreeSet<Student>(new StuComptor());     set.add(stu1);     set.add(stu2);     set.add(stu3);     set.add(stu4);     System.out.println(set.contains(stu2));     for(Student stu:set){         System.out.println(stu);     } }
  | 
 
两种比较方式小结
自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
 
比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
 
在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排序
 
 
两种方式中关于返回值的规则
- 如果返回值为负数,表示当前存入的元素是较小值,存左边
 
- 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
 
- 如果返回值为正数,表示当前存入的元素是较大值,存右边
 
 
Collections
java.utils.Collections是集合工具类,用来对集合进行操作。部分方法如下:
 
public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。
 
public static void shuffle(List<?> list):打乱集合顺序。
 
public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
 
public static <T> void sort(List<T> list,Comparator<? super T> ):将集合中元素按照指定规则排序。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | public static void main(String[] args) {     ArrayList<Integer> list = new ArrayList<Integer>();                                   Collections.addAll(list, 5, 222, 1,2);     System.out.println(list);          Collections.sort(list);     System.out.println(list); }
  | 
 
泛型
泛型的介绍
常情况下集合中可以存放不同类型的对象,是因为将所有对象都看做Object类型放入的,因此 从集合中取出元素时也是Object类型,为了表达该元素真实的数据类型,则需要强制类型转换, 而强制类型转换可能会引发类型转换异常。
 
为了避免上述错误的发生,从Java5开始增加泛型机制,也就是在集合名称的右侧使用<数据类型> 的方式来明确要求该集合中可以存放的元素类型,若放入其它类型的元素则编译报错。
 
泛型只在编译时期有效,在运行时期不区分是什么类型。
 
定义格式:修饰符 class 类名<类型> {}
1 2 3 4 5
   | class ArrayList<E>{     public boolean add(E e){}     public E get(int index){}     .... }
  | 
 
使用在类上的语法
1 2 3 4 5 6 7 8 9
   | public class JavaBean<T> {     private T t;     public T getT() {         return t;     }     public void setT(T t) {         this.t = t;     } }
  | 
 
泛型方法
定义格式:修饰符 <类型> 返回值类型 方法名(类型 变量名) {}
public   void/Integer test(T t)
带有泛型方法的类
1 2 3 4 5
   | public class JavaObject {     public <T> void set(T t){         System.out.println(t);     } }
  | 
 
1 2 3 4 5
   | public static void main(String[] args) {     JavaObject j = new JavaObject();     j.set("hd");     j.set(88); }
  | 
 
泛型接口
定义格式: 修饰符 interface 接口名<类型> {}
1 2 3
   | public interface JavaInterface<T> { void set(T t); }
  | 
 
1 2 3 4 5 6
   | public class JavaObjectImpl1 implements JavaInterface<Integer>{     @Override     public void set(Integer t) {         System.out.println(t);     } }
  | 
 
1 2 3 4 5 6
   | public static void main(String[] args) {     JavaObjectImpl<String> obj1= new JavaObjectImpl<String>();     obj1.set("hd");     JavaObjectImpl<Integer> obj2= new JavaObjectImpl<Integer>();     obj2.set(88); }
  | 
 
类型通配符
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
通配符高级使用—-受限泛型
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。
泛型的上限:
泛型的下限:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | public static void main(String[] args) {     Collection<Integer> list1 = new ArrayList<Integer>();     Collection<String> list2 = new ArrayList<String>();     Collection<Number> list3 = new ArrayList<Number>();     Collection<Object> list4 = new ArrayList<Object>();     getElement(list1);     getElement(list2);     getElement(list3);     getElement(list4);     getElement2(list1);     getElement2(list2);     getElement2(list3);     getElement2(list4); }
  public static void getElement1(Collection<? extends Number> coll){}
  public static void getElement2(Collection<? super Number> coll){}
  | 
 
Map集合
Map集合概述
 interface Map<K,V>  K:键的类型;V:值的类型
Map集合的特点
 
双列集合,一个键对应一个值
 
键不可以重复,值可以重复
 
Map集合的基本功能
| 方法名 | 
说明 | 
| V   put(K key,V   value) | 
添加元素 | 
| V   remove(Object key) | 
根据键删除键值对元素 | 
| void   clear() | 
移除所有的键值对元素 | 
| boolean containsKey(Object key) | 
判断集合是否包含指定的键 | 
| boolean containsValue(Object value) | 
判断集合是否包含指定的值 | 
| boolean isEmpty() | 
判断集合是否为空 | 
| int size() | 
集合的长度,也就是集合中键值对的个数 | 
遍历方法
| 方法名 | 
说明 | 
| V   get(Object key) | 
根据键获取值 | 
| Set   keySet() | 
获取所有键的集合 | 
| Collection   values() | 
获取所有值的集合 | 
| Set<Map.Entry<K,V>>   entrySet() | 
获取所有键值对对象的集合 | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   | public static void main(String[] args) {          Map<String, String> m1 = new HashMap<>();          System.out.println("m1 = " + m1);          String str1 = m1.put("1", "one");     System.out.println("原来的value数值为:" + str1);     System.out.println("m1 = " + m1);     str1 = m1.put("2", "two");     System.out.println("原来的value数值为:" + str1);     System.out.println("m1 = " + m1);     str1 = m1.put("3", "three");     System.out.println("原来的value数值为:" + str1);     System.out.println("m1 = " + m1);          str1 = m1.put("1", "eleven");     System.out.println("原来的value数值为:" + str1);     System.out.println("m1 = " + m1);     System.out.println("----------------");          boolean b1 = m1.containsKey("11");     System.out.println("b1 = " + b1);     b1 = m1.containsKey("1");     System.out.println("b1 = " + b1);     b1 = m1.containsValue("one");     System.out.println("b1 = " + b1);     b1 = m1.containsValue("eleven");     System.out.println("b1 = " + b1);     String str2 = m1.get("5");     System.out.println("str2 = " + str2);     str2 = m1.get("3");     System.out.println("str2 = " + str2);     System.out.println("-------------------------------------");          str2 = m1.remove("1");     System.out.println("被删除的value是:" + str2);     System.out.println("m1 = " + m1);     System.out.println("---------------------------------------");          Set<String> s1 = m1.keySet();          for (String ts : s1) {         System.out.println(ts + "=" + m1.get(ts));     }     System.out.println("-----------------------------------");          Collection<String> co = m1.values();     for (String ts : co) {         System.out.println("ts = " + ts);     }     System.out.println("------------------------------------------");          Set<Map.Entry<String, String>> entries = m1.entrySet();     for (Map.Entry<String, String> me : entries) {         System.out.println(me);     } }
  | 
 
HashMap集合
HashMap集合概述和特点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | public static void main(String[] args) {          String str = "abcaba";               HashMap<Character, Integer> map = new HashMap<>();     for (char zimu:str.toCharArray()) {                  if(map.containsKey(zimu)){                          Integer cishu = map.get(zimu);                          cishu++;             map.put(zimu,cishu);         }else{                          map.put(zimu,1);         }     } }
  | 
 
TreeMap集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
   | public class Student implements Comparable<Student>{     private String name;     private int age;     public Student() {}     public Student(String name, int age) {         this.name = name;         this.age = age;     }     public String getName() {         return name;     }     public void setName(String name) {         this.name = name;     }     public int getAge() {         return age;     }     public void setAge(int age) {         this.age = age;     }     @Override     public String toString() {         return "Student{"+"name='" + name + '\'' +", age=" + age +'}';     }     @Override     public int compareTo(Student o) {                  int result = o.getAge() - this.getAge();                  result = result == 0 ? o.getName().compareTo(this.getName()) : result;         return result;     }s }
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | public class Test1 {     public static void main(String[] args) {         TreeMap<Student,String> tm = new TreeMap<>();         Student s1 = new Student("hd",88);         Student s2 = new Student("jc",99);                  tm.put(s1,"郑州");         tm.put(s2,"北京");                  Set<Map.Entry<Student, String>> entries = tm.entrySet();         for (Map.Entry<Student, String> entry:entries) {             Student key = entry.getKey();             String value = entry.getValue();             System.out.println("key:" + key + "value:" + value);         }     } }
  |