zoukankan      html  css  js  c++  java
  • Java入门笔记 09-集合

    一、Collection接口方法:Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)实现。

    1、添加

    •  add(Object obj)
    •  addAll(Collection coll):将coll中的元素添加到当前集合中

    2、获取有效元素的个数

    •  int size()

    3、清空集合

    •  void clear()

    4、是否是空集合

    •  boolean isEmpty()

    5、是否包含某个元素

    •  boolean contains(Object obj):判断是否包含obj,是通过元素的equals方法来判断是否是同一个对象
    •  boolean containsAll(Collection c):也是调用元素的equals方法来比

    较的。拿两个集合的元素挨个比较。
    6、删除

    •  boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。只会删除找到的第一个元素
    •  boolean removeAll(Collection coll):取当前集合的差集

    7、取两个集合的交集

    •  boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c

    8、集合是否相等

    •  boolean equals(Object obj)

    9、转成对象数组

    •  Object[] toArray()

    10、获取集合对象的哈希值

    •  hashCode()

    11、遍历

    •  iterator():返回迭代器对象,用于集合遍历

    二、Iterator迭代器接口

    • Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。迭代器模式,就是为容器而生;
    • Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象;
    • Iterator 仅用于遍历集合,Iterator 本身并不提供承装对象的能力,如果需要创建Iterator 对象,则必须有一个被迭代的集合;
    • 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
     1 @Test //迭代器中的remove()
     2 public void test2(){
     3     Collection collection1 = new ArrayList();
     4     collection1.add("A");
     5     collection1.add("B");
     6     collection1.add("Jerry");
     7 
     8     //移除操作
     9     Iterator iterator = collection1.iterator();
    10     while(iterator.hasNext()){
    11         Object next = iterator.next();
    12         if("B".equals(next))
    13             iterator.remove();
    14 
    15     }
    16 
    17     //从头开始遍历
    18     iterator = collection1.iterator();//必须重新生成,不然接上面的集合最后
    19     while(iterator.hasNext()){
    20         System.out.println(iterator.next());
    21     }
    22 }

      注意:

    • Iterator可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。
    • 如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException。

    三、Collection子接口——List:List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。

      1. List接口常用方法

    • 增:add(Object o)
    • 删:remove(int index)/remove(Object o)
    • 改:set(int index, Object o)
    • 查:get(int index)
    • 插:add(int index, Object o)
    • 长度:size()
    • 遍历:

        |--- Iterator迭代器
        |--- for
        |--- foreach

     1 public class ListTest {
     2     @Test
     3     public void test1(){
     4         ArrayList list = new ArrayList();
     5         list.add(123);
     6         list.add("A");
     7         list.add(456);
     8         System.out.println("原始:" + list);
     9 
    10         //void add(int index, Object ele):在index位置插入ele元素
    11         list.add(0,"B");
    12         System.out.println("add(0,B):" + list);
    13 
    14         //boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
    15         List list1 = Arrays.asList(1,2,3);
    16         list.addAll(2,list1);
    17         System.out.print("list1" + list1 + "*** ");
    18         System.out.println("addAll(2,list1):" + list);
    19 
    20         //Object get(int index):获取指定index位置的元素
    21         System.out.println(list.get(0));
    22     }
    23 
    24     @Test
    25     public void test2(){
    26         ArrayList list = new ArrayList();
    27         list.add(456);
    28         list.add(123);
    29         list.add("A");
    30         list.add(456);
    31         System.out.println("原始:" + list);
    32 
    33         //int indexOf(Object obj):返回obj在集合中首次出现的位置,没有返回-1
    34         System.out.println(list.indexOf("A"));//2
    35 
    36         //int lastIndexOf(Object obj):返回obj在当前集合中最后一次出现的位置
    37         System.out.println(list.lastIndexOf(456));//3
    38 
    39         //Object remove(int index):移除指定index位置的元素,并返回此元素
    40         System.out.println(list.remove(0));
    41         System.out.println("remove 0 后:" + list);
    42 
    43         //Object set(int index, Object ele):设置指定index位置的元素为ele,并返回index处的元素
    44         System.out.println(list.set(0,567));
    45         System.out.println("set(0,567)后:" + list);
    46 
    47         //List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合,左闭右开
    48         System.out.println("subList(0,2): " + list.subList(0,2));
    49         System.out.println("list: " + list);
    50     }
    51 
    52     //遍历
    53     @Test
    54     public void test3(){
    55         ArrayList list = new ArrayList();
    56         list.add(456);
    57         list.add(123);
    58         list.add("A");
    59         list.add(456);
    60 
    61         //Iterator迭代器
    62         Iterator iterator = list.iterator();
    63         while(iterator.hasNext())
    64             System.out.println(iterator.next());
    65         System.out.println();
    66 
    67         //foreach
    68         for(Object o: list){
    69             System.out.println(o);
    70         }
    71         System.out.println();
    72 
    73         //for
    74         for(int i=0;i<list.size();i++)
    75             System.out.println(list.get(i));
    76     }
    77 }

      2. List的实现类ArrayList:ArrayList 是 List 接口的典型实现类、主要实现类,非线程安全,效率高,底层使用Object数组存储。

      3. List的实现类LinkedList:对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高,底层是双向链表,新增如下方法:

    • void addFirst(Object obj)
    • void addLast(Object obj)
    • Object getFirst()
    • Object getLast()
    • Object removeFirst()
    • Object removeLast()

      4. List的实现类Vector:Vector 是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。

      面试题:请问ArrayList/LinkedList/Vector的异同?谈谈你的理解?ArrayList底层是什么?扩容机制?Vector和ArrayList的最大区别?

      ArrayList和LinkedList的异同:

    • 二者都线程不安全,相对线程安全的Vector,执行效率高。
    • 此外,ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。对于新增和删除操作add(特指插入)和remove,LinkedList比较占优势,因为ArrayList要移动数据。

      ArrayList和Vector的区别:

    • Vector和ArrayList几乎是完全相同的,唯一的区别在于Vector是同步类(synchronized),属于强同步类。因此开销就比ArrayList要大,访问要慢。正常情况下,大多数的Java程序员使用ArrayList而不是Vector,因为同步完全可以由程序员自己来控制。
    • Vector每次扩容请求其大小的2倍空间,而ArrayList是1.5倍。Vector还有一个子类Stack。

    四、Collection子接口——Set:Set接口是Collection的子接口,set接口没有提供额外的方法,Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set 集合中,则添加操作失败。Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法。

      1. Set的实现类HashSet:HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。

      HashSet 具有以下特点:

    • 不能保证元素的排列顺序
    • HashSet 不是线程安全的
    • 集合元素可以是 null

      HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。因此对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Objectobj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。

      添加元素的过程,以HashSet为例:首先利用hash值确定index,若此index上有元素:

    • hash值不同,添加成功
    • hash值相同,调用该对象所在类的equals方法
      •     true:添加失败
      •     false:添加成功

      2. Set的实现类LinkedHashSet:是 HashSet 的子类,根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的。LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

     1 @Test
     2 public void test2(){
     3     Set set = new LinkedHashSet();
     4     set.add(123);
     5     set.add(456);
     6     set.add("A");
     7     set.add(new Integer(789));
     8 
     9     Iterator iterator = set.iterator();
    10     while(iterator.hasNext())
    11         System.out.println(iterator.next());
    12 }

      3. Set的实现类TreeSet:是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态,使用红黑树结构存储数据。新增如下方法:

    • Comparator comparator()
    • Object first()
    • Object last()
    • Object lower(Object e)
    • Object higher(Object e)
    • SortedSet subSet(fromElement, toElement)
    • SortedSet headSet(toElement)
    • SortedSet tailSet(fromElement)

      3.1 自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。因此如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable接口。向 TreeSet 中添加元素时,只有第一个元素无须比较compareTo()方法,后面添加的所有元素都会调用compareTo()方法进行比较。因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象。对于 TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过 compareTo(Object obj) 方法比较返回值,不再是equals方法。

     1 public class TreeSetTest {
     2     @Test
     3     public void test2(){
     4         TreeSet set = new TreeSet();
     5         set.add(new User("Amy",12));
     6         set.add(new User("Bob",13));
     7         set.add(new User("Emily", 14));
     8         set.add(new User("Dean", 15));
     9         set.add(new User("Dean", 16));
    10 
    11         Iterator iterator = set.iterator();
    12         while(iterator.hasNext())
    13             System.out.println(iterator.next());
    14     }
    15 }
    16 
    17 class User implements Comparable{
    18     private String name;
    19     private int age;
    20 
    21     public User() {
    22     }
    23 
    24     public User(String name, int age) {
    25         this.name = name;
    26         this.age = age;
    27     }
    28 
    29     public String getName() {
    30         return name;
    31     }
    32 
    33     public void setName(String name) {
    34         this.name = name;
    35     }
    36 
    37     public int getAge() {
    38         return age;
    39     }
    40 
    41     public void setAge(int age) {
    42         this.age = age;
    43     }
    44 
    45     @Override
    46     //按照姓名从大到小排列,年龄从小到大
    47     public int compareTo(Object o) {
    48         if(o instanceof User){
    49             User user = (User)o;
    50             int compare = -this.name.compareTo(user.name);
    51             if(compare == 0){
    52                 return Integer.compare(this.age, user.age);
    53             }else
    54                 return compare;
    55 
    56         }else{
    57             throw new RuntimeException("输入的类型不匹配");
    58         }
    59     }
    60 
    61     /*
    62     @Override
    63     //按照姓名从小到大排列
    64     public int compareTo(Object o) {
    65         if(o instanceof User){
    66             User user = (User)o;
    67             return this.name.compareTo(user.name);
    68         }else{
    69             throw new RuntimeException("输入的类型不匹配");
    70         }
    71     }
    72     */
    73 
    74     @Override
    75     public String toString() {
    76         return "name: " + name + ", age: " + age;
    77     }
    78 }

      3.2 定制排序:在定制排序中,比较两个对象是否相同的标准为:compare方法的返回值,不再是equals方法。

     1 @Test
     2 public void test3(){
     3     Comparator com = new Comparator() {
     4         //按照年龄从小到大,年龄一样的数据只要一个
     5         @Override
     6         public int compare(Object o, Object t1) {
     7             if(o instanceof User && t1 instanceof User){
     8                 User u1 = (User)o;
     9                 User u2 = (User)t1;
    10                 return Integer.compare(u1.getAge(), u2.getAge());
    11             }else{
    12                 throw new RuntimeException("输入的数据类型不匹配");
    13             }
    14         }
    15     };
    16 
    17     TreeSet set = new TreeSet(com);
    18     set.add(new User("Amy",12));
    19     set.add(new User("Bob",12));
    20     set.add(new User("Emily", 14));
    21     set.add(new User("Dean", 15));
    22     set.add(new User("Dean", 16));
    23 
    24     Iterator iterator = set.iterator();
    25     while(iterator.hasNext())
    26         System.out.println(iterator.next());
    27 }

    五、Map接口:用于保存具有映射关系的数据:key-value,类似与高中讲的函数的概念。

      0. Map结构的理解:

    • key:无序、不可重复,使用Set存储所有的key;--->要求key所在的类重写equals和hashcode方法(以HashMap为例的)
    • value:无序、可重复,使用Collection存储所有的value。--->要求value所在的类重写equals方法
    • 一个key-value对构成了一个Entry对象。entry是无序、不可重复的。

    1. Map接口常用方法

     1 public class MapTest {
     2     @Test
     3     //增删改
     4     public void test1(){
     5         //put
     6         HashMap hashMap = new HashMap();
     7         hashMap.put("AA",123);
     8         hashMap.put("BB",456);
     9         hashMap.put("CC",789);
    10         hashMap.put("AA",101);
    11 
    12         System.out.println(hashMap);//{AA=101, BB=456, CC=789}相当于原有的123被改为101
    13 
    14         //putAll
    15         HashMap hashMap1 = new HashMap();
    16         hashMap1.put("DD",102);
    17         hashMap1.putAll(hashMap);
    18         System.out.println(hashMap1);
    19 
    20         //remove(key),返回对应key的value并删除该entry
    21         System.out.println(hashMap.remove("AA"));
    22         System.out.println(hashMap);
    23 
    24         //clear
    25         hashMap1.clear();
    26         System.out.println(hashMap1);
    27     }
    28 
    29     @Test
    30     //查询
    31     public void test2(){
    32         HashMap hashMap = new HashMap();
    33         hashMap.put("AA",123);
    34         hashMap.put("BB",456);
    35         hashMap.put("CC",789);
    36 
    37         //get
    38         System.out.println(hashMap.get("AA"));
    39 
    40         //containsKey
    41         System.out.println(hashMap.containsKey("DD"));
    42 
    43         //containsValue
    44         System.out.println(hashMap.containsValue(789));
    45 
    46         //size
    47         System.out.println(hashMap.size());
    48 
    49         //isEmpty
    50         System.out.println(hashMap.isEmpty());
    51     }
    52 
    53     @Test
    54     //遍历
    55     public void test3(){
    56         HashMap hashMap = new HashMap();
    57         hashMap.put("AA",123);
    58         hashMap.put("BB",456);
    59         hashMap.put("CC",789);
    60 
    61         //keySet,返回一个Set
    62         Set set = hashMap.keySet();
    63         Iterator iterator = set.iterator();
    64         while(iterator.hasNext())
    65             System.out.println(iterator.next());
    66 
    67         //values,返回一个Collection
    68         Collection values = hashMap.values();
    69         Iterator iterator2 = values.iterator();
    70         while(iterator2.hasNext())
    71             System.out.println(iterator2.next());
    72 
    73         //entrySet,返回一个Set
    74         Set set1 = hashMap.entrySet();
    75         Iterator iterator1 = set1.iterator();
    76         while(iterator1.hasNext()){
    77             Object object = iterator1.next();
    78             Map.Entry entry = (Map.Entry) object;
    79             System.out.println(entry.getKey() + "--->" + entry.getValue());
    80         }
    81     }
    82 }

    2. HashMap:作为Map的主要实现类,线程不安全,效率高,可以存储null,底层是数组+链表(jdk8及以后+红黑树)

    3. LInkedHashMap:作为HashMap的子类,保证了遍历map元素时按照添加时的顺序遍历。对于频繁遍历的操作,此类执行的效率高于HashMap

    4. TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然/定制排序,底层使用红黑树。要求都是同一个类

     1 public class TreeMapTest {
     2 
     3     @Test
     4     //自然排序
     5     public void test1(){
     6         TreeMap map = new TreeMap();
     7         User u1 = new User("Tom",23);
     8         User u2 = new User("Jack",12);
     9         User u3 = new User("Bob",21);
    10 
    11         map.put(u1, 90);
    12         map.put(u2, 81);
    13         map.put(u3, 62);
    14 
    15         Set set1 = map.entrySet();
    16         Iterator iterator1 = set1.iterator();
    17         while(iterator1.hasNext()){
    18             Object object = iterator1.next();
    19             Map.Entry entry = (Map.Entry) object;
    20             System.out.println(entry.getKey() + "--->" + entry.getValue());
    21         }
    22     }
    23 
    24     @Test
    25     //定制排序:定制按照年龄排序
    26     public void test2(){
    27         TreeMap map = new TreeMap(new Comparator() {
    28             @Override
    29             public int compare(Object o1, Object o2) {
    30                 if(o1 instanceof User && o2 instanceof User){
    31                     User u1 = (User)o1;
    32                     User u2 = (User)o2;
    33                     return Integer.compare(u1.getAge(), u2.getAge());
    34                 }
    35                 throw new RuntimeException("输入的类型不匹配");
    36             }
    37         });
    38         User u1 = new User("Tom",23);
    39         User u2 = new User("Jack",12);
    40         User u3 = new User("Bob",21);
    41 
    42         map.put(u1, 90);
    43         map.put(u2, 81);
    44         map.put(u3, 62);
    45 
    46         Set set1 = map.entrySet();
    47         Iterator iterator1 = set1.iterator();
    48         while(iterator1.hasNext()){
    49             Object object = iterator1.next();
    50             Map.Entry entry = (Map.Entry) object;
    51             System.out.println(entry.getKey() + "--->" + entry.getValue());
    52         }
    53     }
    54 }

    5. Hashtable:作为古老的实现类,线程安全的,效率低,不能存储null

      |--- Properties:常用来处理配置文件,key和value都是String类型。

     1 public class PropertiesTest {
     2     public static void main(String[] args) throws IOException {
     3         Properties properties = new Properties();
     4 
     5         FileInputStream fis = new FileInputStream("jdbc.properties");
     6         properties.load(fis);
     7 
     8         String name = properties.getProperty("name");
     9         String password = properties.getProperty("password");
    10 
    11         System.out.println(name + " " + password);
    12     }
    13 }

    六、Collections工具类:Collections 是一个操作 Set、List 和 Map 等集合的工具类

      1. 排序操作:(均为static方法)

    • reverse(List):反转 List 中元素的顺序
    • shuffle(List):对 List 集合元素进行随机排序
    • sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
    • sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
    • swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换

      2. 查找、替换

    • Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
    • Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
    • Object min(Collection)
    • Object min(Collection,Comparator)
    • int frequency(Collection,Object):返回指定集合中指定元素的出现次数
    • void copy(List dest,List src):将src中的内容复制到dest中
    • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List 对象的所有旧值
     1 public class CollectionsTest {
     2     @Test
     3     public void test(){
     4         List list = new ArrayList();
     5         list.add(1);
     6         list.add(2);
     7         list.add(3);
     8 
     9         List list1 = Arrays.asList(new Object[list.size()]);
    10         Collections.copy(list1, list);
    11         System.out.println(list1);
    12     }
    13 }
  • 相关阅读:
    ODBC连接数据库
    发送邮件
    动态控制某些字段可以修改
    动态调用SQL和存储过程
    写数据到TXT文档
    动态创建Form
    动态调用报表
    ICE学习笔记2:摸了这么些天,终于有点着道了
    如何使用 Symbol Retriever
    Win XP注册表之性能优化
  • 原文地址:https://www.cnblogs.com/dailymatters/p/12325840.html
Copyright © 2011-2022 走看看