zoukankan      html  css  js  c++  java
  • JAVA基础知识之练习题——集合

    练习一:

    创建一个Set集合,保存用户输入的数据

    具体代码实现如下面代码中的testSet()方法。

    知识点:

    1. Set集合的基本特征是元素不允许重复。HashSet不保存元素顺序,LinkedHashSet用链表保持元素的插入顺序,TreeSet可定制排序规则。
    2. HashSet的底层是用HashMap实现的,即HashMap<key, value>中把所有value置为null,key就组成了一个Set
    3. HashSet把元素的hashCode值作为地址索引来存储元素,可以实现类似根据数组下标索引查找元素的效果,这是HashSet访问速度快的原因
    4. HashSet中如果两个元素通过equals比较结果为true,但是两个元素的hashCode不相等,即在两个地方存放了值相等的两个元素,HashSet将会出现各种奇怪问题,不能正常工作。
    5. 基于上面第4点,HashSet元素判断两个元素相等的标准是,不仅需要equals比较的结果为true,而且需要元素hashCode值相等,即不允许equals比较为true但是hashCode不想等的两个元素存放在HashSet中。
    6. HashSet中允许equals比较为false但是hashCode相等的两个元素同时存在,这两个元素将会被存放在同一个位置,并用链表维持两个元素顺序,但是这将严重影响HashSet的性能。
    7. 基于上面4.5.6点,如果需要重写一个HashSet的equals方法,一定也要重写hashCode方法,原则是如果equals方法和equals方法使用共同的变量(成员变量)做计算,使得如果equals为true,hashCode结果值要相等。
    8. LinkedHashSet底层多了一个链表结构用来保存元素的插入顺序(插入位置还是由hashCode决定的),遍历LinkedHashSet时会自动根据链表来遍历
    9. TreeSet的元素是有序的,有两种排序规则,默认是按自然排序(在元素中写排序规则,元素必须实现了Comparable接口,且元素类型必须一样),另一种是定制排序(由集合实现排序规则,需要集合关联一个Comparator对象实现)
    10. JAVA中接收键盘输入用System.in.read(), 这个方法接收的是byte[]字节,当输入结束(回车)时返回-1,但是这个方法会同时将 和 也接收。BufferedReader的readLine()方法可以读取一行,适应各种平台的断行规则(自动去除换行符 , 等),但是BufferedReader只能读取stream类型,System.in只能返回byte类型,因此需要用InputStreamReader做转换。

    练习二

     创建一个List集合,随意添加10个元素,然后通过索引为5处的元素,再取其中某个元素的索引,再删除索引为3的元素

    实现代码如下面的testList()

    知识点,

    1. List集合的基本特征是元素有序,可重复,每个元素都有顺序索引。因此List集合可以像数组一样使用。
    2. List集合有一个专用迭代器ListIterator,可以实现反向迭代。
    3. ArrayList和Vector底层使用一个智能数组实现,可动态扩展(ensureCapacity(int i)重新分类空间),
    4. 在java.util.Arrays 的内部也定义了一个ArrayList (通过asList()方法返回),但这是一个不可变定长数组,不能增加,删除数组元素,否则会抛出异常。
    5. Vector是一个古老的集合实现类,Vector所拥有的功能ArrayList基本都有。但是Vector是一个线程安全类,性能上会比ArrayList稍低。另外Vector还有一个子类Stack,实现了栈结构。
    6. LinkedList是List的实现类,同时又是Deque的实现类,因此LinkedList同时具有ArrayList(随机存取)和ArrayDeque(双端队列,栈)的功能。但是LinkedList的内部实现完全不同,LinkedList内部使用链表实现,虽然也LinkedList表面上使用的是index索引数组方式的随机访问,但是内部实现的时候使用index关联了链表的顺序,依然使用的是迭代访问,所以性能上比ArrayList差。不过插入和删除性能更好。

    练习三

    给定["a","b","a","b","c","a","b","c"]数组,使用Map的key保存字符串的元素,用value保存元素出现的次数

    实现代码如下面的testMap()

    知识点

    1. Map 的基本特征是key不重复。key和set存在单向一对一关系。
    2. Map接口中有两个重要的数据结构,一个是keySetp,用Set集合保存了所有key;一个是内部类Entry,用来封装key-value对,每个元素对应一个Entry对象,保存在Map的全局数组transient Entry table[];中。
    3. Map的entrySet()方法可以返回一个Entry对象组成的的Set集合的视图。注意entrySet中并没有使用一个Set对象来保存所有Entry集合,而是定义一个EntrySet内部类,其中有个iterator()方法可以迭代访问map的所有Entry对象,调用EntrySet的iterator()方法就相当于得到了Entry集合的视图。
    4. HashMap中,每次put进一个新元素时,都会在底层new一个Entry类来关联key-value,并将Entry对象保存在Map的全局数组transient Entry table[];中
    5. 由上面可知遍历HashMap至少有四种方法。1)集合通用方法value = iterator.next。 2)map常规方法 value=map.get(key).  3)遍历entrySet集合。  value=map.entrySet.getValue(). 4)遍历values集合 value=map.values...
    6. HashMap和Hashtable的关系,可以类比HashSet跟Vector.  Hashtable是一个古老的,线程安全的集合。
    7. HashMap跟HashSet判断元素是否相等的标准一样,都是需要同时满足equals为true,且元素hashCode值相等才认为是相同元素。 equals为true但hashCode不相等的两个元素可以存入map中,但是不能正常工作;equals为false但hashCode相等会认为是不同元素,存放在同一个地方,用链表关联value,性能低。
    8. LinkedHashMap跟linkedHashSet一样,也用(双向)链表维护元素的插入顺序(key顺序)。

    以上三个练习题实现代码如下,

      1 package test;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.IOException;
      5 import java.io.InputStreamReader;
      6 import java.util.ArrayList;
      7 import java.util.HashMap;
      8 import java.util.HashSet;
      9 import java.util.Iterator;
     10 import java.util.LinkedHashSet;
     11 import java.util.LinkedList;
     12 import java.util.List;
     13 import java.util.Map;
     14 import java.util.Set;
     15 import java.util.TreeSet;
     16 
     17 class A {
     18     public int count;
     19     public A(int count) {
     20         this.count = count;
     21     }
     22     
     23     public boolean equals(Object obj){
     24         if (this == obj) {
     25             return true;
     26         }
     27         if (obj != null && obj.getClass() == A.class) {
     28             A r = (A)obj;
     29             return r.count == this.count;
     30         }
     31         return false;
     32     }
     33     
     34     public int hashCode() {
     35         return this.count;
     36     }
     37     
     38     public String toString() {
     39         return this.count+"";
     40     }
     41     
     42 }
     43 public class TestCollection {
     44     //练习一:创建一个Set集合,保存用户输入的数据
     45     public static void testSet() throws Exception {
     46         /*
     47          * LinkdedHashSet可以保持插入顺序
     48          * Set set = new LinkedHashSet();
     49          */
     50         
     51         /*
     52          * TreeSet需要实现排序规则,自然排序的元素是要元素实现Comparable接口,定制排序是要集合关联Comparator对象
     53          * Set set = new TreeSet();
     54          */
     55         
     56         //HashSet无序,不重复
     57         Set set = new HashSet();
     58         int keyIn;
     59         int num = 0;
     60         
     61         while ( num++ < 2) {
     62             /*
     63              * Scanner可以方便将键盘输入转换成各种类型
     64              * Scanner sc = new Scanner(System.in);
     65              * keyIn = sc.nextInt();
     66              */
     67             
     68             /*
     69              * BufferedReader的readLine()方法可以读取一行,可以适应各种平台的断行规则
     70              * 但是BufferedReader只能读取stream类型,System.in只能返回byte类型,因此需要用InputStreamReader做转换
     71              */
     72             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     73             keyIn = Integer.parseInt(br.readLine());
     74             set.add(new A(keyIn));
     75         }
     76         System.out.println(set);
     77     }
     78     //练习二
     79     public static void testList() {
     80         List list = new LinkedList();
     81         //List list = new ArrayList();
     82         for (int i=0; i<10; i++) {
     83             list.add(new A(i));
     84         }
     85         list.add(new A(5));
     86         System.out.println(list);
     87         System.out.println(list.get(5));
     88         //这里虽然用的是new A(6),但是在list中仍然可以找到这个元素,原因是在上面的class A中重写了equal和hashCode方法
     89         System.out.println(list.indexOf(new A(6)));
     90         System.out.println(list.remove(3));
     91         System.out.println(list);
     92     }
     93     //练习三
     94     public static void testMap() {
     95         String[] str = new String[] {"a","b","a","b","c","a","b","c"};
     96         Map<String, Integer> map = new HashMap();
     97         Set<String> set = new LinkedHashSet();
     98         for (int i = 0; i < str.length; i++) {
     99             set.add(str[i]);
    100         }
    101         
    102         String key;
    103         Iterator it = set.iterator();
    104         while (it.hasNext()) {
    105             int val = 0;
    106             key = (String)it.next();
    107             for (int i = 0; i < str.length; i++) {
    108                 if (str[i] == key) val++;
    109             }
    110             map.put(key, val);
    111         }
    112 
    113         System.out.println(map);
    114     }
    115     
    116     public static void main(String[] args) throws Exception {
    117         //TestCollection.testSet();
    118         TestCollection.testList();
    119         //TestCollection.testMap();
    120     }
    121 }
  • 相关阅读:
    .NET 3.5新特性(转)
    (转)常用正则表达式
    IEC 61850(转)
    好几年了,我又回来了。
    EPR和SAP的一些名词解释(转载)
    为blogs添加风采,添加奥运金牌榜及赛程
    VS2010崩溃重启解决方法.
    C#制作Windows service服务系列二:演示一个定期执行的windows服务及调试(windows service)(转载)
    C#中操作XML (修改完整版) (转)
    C#制作Windows service服务系列一:制作一个可安装、可启动、可停止、可卸载的Windows service
  • 原文地址:https://www.cnblogs.com/fysola/p/6114914.html
Copyright © 2011-2022 走看看