zoukankan      html  css  js  c++  java
  • 渣渣小本求职复习之路每天一博客系列——Java基础(6)

      前情回顾:上一篇除了回顾了异常处理的后半部分之外,还进行了对Collection的初步了解,包括它的继承和实现架构以及各子类的特性以及用法。

      不知道大家有没有这样的经历,就是自己在寻求别人的帮助时,有时候会因为对方的没有痛快答应而感到恼火。自己私底下再想想,告诉自己别人真没有必须要帮助自己的义务,真不能对他们要求太多。想着想着,转而会觉得自己好没用,怎么就知道靠别人。就这样,被自尊和自卑不清不楚地折磨着。

      若是能够走出来倒是好。如果确定某些事情必须只能靠自己去完成,某些困难只能靠自己去克服,那就绝不要怨天尤人,责怪没人帮助自己。像日本动漫里面的热血主人公一样,在心里大喊一句:少年,勇敢起来, 冲吧!然后该做什么,就做什么,做完做好就对了。

    ————————————————————————闲聊结束—————————————————————————————

      第八章:Collection

      第五节:访问对象的Iterator

      其实,详细看过API说明文档Collection部分的童鞋都应该有印象。在Collection接口中,有定义一个方法,就是这一节的主题——iterator()方法会返回java.util.Iterator接口的实现对象,这个对象包括了Collection收集的所有对象。我们可以使用Iterator的hasNext()看看有无下一个对象,若有的话,再使用next()取得下一个对象。因此,无论List、Set、Queue还是任何Collection,都可以使用以下的forEach()来显示所收集的对象:

    1 ...
    2     private static void forEach(Collection collection){
    3         Iterator iterator = collection.iterator();
    4         while(iterator.hasNext()){
    5             System.out.println(iterator.next());
    6         }
    7     }
    8 ...

      任何实现了Iterable的对象,都可以使用整个forEach()方法,而不一定是Collection。

      第六节:对收集的对象进行排序

      相信学过数据结构与常用算法的童鞋都对几个排序算法比较熟悉,例如冒泡、归并、快排等。在java中,排序是常用的方法,不用我们亲自去实现。java.util.Collection就有提供sort()方法以供排序。要想排序,必须得有索引才行,因此Collection的sort()方法把实现List的对象作为参数。看到以下的示例代码:

     1 package cc.openhome;
     2 
     3 import java.util.*;
     4 
     5 public class Sort {
     6     public static void main(String[] args) {
     7         List numbers = Arrays.asList(10, 2, 3, 1, 9, 15, 4);
     8         Collections.sort(numbers);
     9         System.out.println(numbers);
    10     }
    11 }

      可是,如果是下面的例子,却会出现异常

     1 package cc.openhome;
     2 
     3 import java.util.*;
     4 
     5 class Account {
     6     private String name;
     7     private String number;
     8     private int balance;
     9 
    10     Account(String name, String number, int balance) {
    11         this.name = name;
    12         this.number = number;
    13         this.balance = balance;
    14     }
    15 
    16     @Override
    17     public String toString() {
    18         return String.format("Account(%s, %s, %d)", name, number, balance);
    19     }
    20     
    21 }
    22 
    23 public class Sort2 {
    24     public static void main(String[] args) {
    25         List accounts = Arrays.asList(
    26                 new Account("Justin", "X1234", 1000),
    27                 new Account("Monica", "X5678", 500),
    28                 new Account("Irene", "X2468", 200)
    29         );
    30         Collections.sort(accounts);
    31         System.out.println(accounts);
    32     }
    33 }

      异常如下截图:

      抛出这个异常,是因为我们的程序没有告诉sort()方法到底要根据Account的name、number或balance进行排序。Collections的sort()方法要求被排序的对象,必须实现java.lang.Comparable接口,这个接口有个compareTo()方法必须返回大于0、等于0或小于0的数。可是,这又有什么用呢?先看看下面的代码:

     1 package cc.openhome;
     2 
     3 import java.util.*;
     4 
     5 class Account2 implements Comparable {
     6     private String name;
     7     private String number;
     8     private int balance;
     9 
    10     Account2(String name, String number, int balance) {
    11         this.name = name;
    12         this.number = number;
    13         this.balance = balance;
    14     }
    15 
    16     @Override
    17     public String toString() {
    18         return String.format("Account2(%s, %s, %d)", name, number, balance);
    19     }
    20 
    21     @Override
    22     public int compareTo(Object o) {
    23         Account2 other = (Account2) o;
    24         return this.balance - other.balance;
    25     }
    26 }
    27 
    28 public class Sort3 {
    29     public static void main(String[] args) {
    30         List accounts = Arrays.asList(
    31                 new Account2("Justin", "X1234", 1000),
    32                 new Account2("Monica", "X5678", 500),
    33                 new Account2("Irene", "X2468", 200)
    34         );
    35         Collections.sort(accounts);
    36         System.out.println(accounts);
    37     }
    38 }

      Collections的sort()方法在取得a对象与b对象进行比较时,会先将a对象扮演(Cast)为Comparable(也因此若对象没实现Comparable,将会抛出ClassCastException),然后调用a.compareTo(b),如果a对象顺序上小于b对象,必须返回小于0的值,若顺序上相等则返回0,若大于则返回大于0的值。为什么前面的Sort类中,可以直接对Integer进行排序呢?若查看API文档,我们就可以发现,Integer实现了Comparable接口。

      第七节:使用泛型

      Collection收集对象的时候,考虑到会收集各种对象,所以内部实现采用了Object参考收集的对象,所以执行时期被收集的对象会失去形态信息,也因此取回对象之后,必须自行记得对象的真正类型,并在语法上告诉编译程序让对象重新扮演为自己的类型。

      Collection虽然可以收集各种对象,但实际上通常只会收集同一种类型的对象,例如都是收集Integer对象。在JDK5之后,新增了泛型(Genertics)语法,让我们在设计API时可以指定类或方法支持泛型,而是用API的客户端在语法上会更为简洁,并得到编译时期检查。加入泛型语法的ArrayList示范:

     1 package cc.openhome;
     2 
     3 import java.util.Arrays;
     4 
     5 public class ArrayList<E> {
     6     private Object[] list;
     7     private int next;
     8    
     9     public ArrayList(int capacity) {
    10         list = new Object[capacity];
    11     }
    12 
    13     public ArrayList() {
    14         this(16);
    15     }
    16 
    17     public void add(E e) {
    18         if(next == list.length) {
    19             list = Arrays.copyOf(list, list.length * 2);
    20         }
    21         list[next++] = e;
    22     }
    23     
    24     public E get(int index) {
    25         return (E) list[index];
    26     }
    27     
    28     public int size() {
    29         return next;
    30     }
    31 }

      注意到类名称盘的角括号<E>,这表示这个类支持泛型。实际加入ArrayList的对象会是客户端声明的E类型。当然了,E(Element)只是一个类型代号,我们可以用A~Z都行。由于使用<E>定义类型,在需要编译程序检查类型的地方,都可以使用E,例如add()方法必须检查传入的对象类型是E,get()方法必须转换为E类型。

     

      Collection就进行到这里了。更多的内容,尤其是关于泛型的语法细节,我们会在后面的博客中介绍。

     

      第九章:键-值对应的Map

      根据某个键(Key)来取得对应的值(Value),我们可以用实现java.util.Map接口的类对象来建立键值对应数据。建立之后,如果要取得值,只要用对应的键就可以迅速取得。

      第一节:Map设计架构

      先了解一下Map设计架构,对正确使用API帮助相当大,至少不会稀里糊涂。

      

      常用的Map实现类有java.util.HashMap与java.util.TreeMap,都继承了抽象类java.util.AbstractMap。至于Dictionary和HashTable是JDK1.0遗留下来的API,不被建议使用,但是图上没有的java.util.Properties是HashTable的子类,却是挺常用的。

      第二节:HashMap

      Map支持上一章最后提到的泛型语法,我们先直接来看一个范例,可以根据用户名称取得对应的信息:

     1 package cc.openhome;
     2 
     3 import java.util.*;
     4 
     5 public class Messages {
     6     public static void main(String[] args) {
     7         Map<String, String> messages = new HashMap<>();   //以泛型语法指定键值类型
     8         messages.put("Justin", "Hello!Justin的信息!");  //建立键值对应
     9         messages.put("Monica", "给Monica的悄悄话!");
    10         messages.put("Irene", "Irene的可爱猫喵喵叫!");
    11         
    12         Scanner scanner = new Scanner(System.in);
    13         System.out.print("取得谁的信息:");
    14         String message = messages.get(scanner.nextLine()); //根据键取回值
    15         System.out.println(message);
    16         System.out.println(messages);
    17     }
    18 }

      建立Map实现对象的时候,可以使用泛型语法来指定键-值的类型。在这里键使用String,值也使用String类型。要建立键值对应,可以使用put()方法,第一个自变量是键,第二个变量是值。键,是不会重复的。如果要指定键取回对应的值,则使用get()方法。那么,大家知不知道,如果我们指定的键不存在,会有什么样的结果呢?这次先不看API文档,来一段源代码好了。

     1     public V get(Object key) {
     2         if (key == null)
     3             return getForNullKey();
     4         int hash = hash(key.hashCode());
     5         for (Entry<K,V> e = table[indexFor(hash, table.length)];
     6              e != null;
     7              e = e.next) {
     8             Object k;
     9             if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
    10                 return e.value;
    11         }
    12         return null;
    13     }

      根据这个get方法,我们很明显能看到,如果我们的key等于null,那么就会返回getForNullKey()的结果,如果key不为null也不在HashMap里,那就会返回null。(哈哈,这算是我第一次看JDK的源代码吧)。那getForNullKey()的结果是什么呢?其实Key的可以设为null,如果我们有一个键的值为null,get()方法就会返回键对应的值,如果不存在,则还是会返回null。

      第三节:TreeMap

      在HashMap中建立键值对应之后,键是无序的。如果想排序,我们可以用TreeMap。不过条件是作为键盘的对象必须实现Compareable接口,或者是在创建TreeMap时指定实现Comparable接口的对象。例如下面这个范例:

     1 package cc.openhome;
     2 
     3 import java.util.*;
     4 
     5 public class Messages2 {
     6     public static void main(String[] args) {
     7         Map<String, String> messages = new TreeMap<>(); 
     8         messages.put("Justin", "Hello!Justin的信息!");
     9         messages.put("Monica", "给Monica的悄悄话!");
    10         messages.put("Irene", "Irene的可爱猫喵喵叫!");
    11         System.out.println(messages);
    12     }
    13 }

      由于String实现了Comparable接口,因此我们可以看到结果是排序的。(截图就不贴出来了,大家去试试吧。)

      第四节:访问键值

      有的时候,我们可能需要取得Map中所有的值,或者是想取得Map中所有的值。Map虽然跟Collection没有继承上的关系,然而却是彼此配合的API。

      如果想要取得Map中所有的键,可以调用Map的keySet()返回Set对象。由于键是不重复的,所以用Set返回是当然的;如果想要取得Map中所有的值,则可以使用values()返回Collection对象。看下面这段代码:

     1 package cc.openhome;
     2 
     3 import java.util.*;
     4 
     5 public class MapKeyValue {
     6     public static void main(String[] args) {
     7         Map<String, String> map = new HashMap<>();
     8         map.put("one", "一");
     9         map.put("two", "二");
    10         map.put("three", "三");
    11         
    12         System.out.println("显示键");
    13         foreach(map.keySet());
    14         
    15         System.out.println("显示值");
    16         foreach(map.values());
    17     }
    18     
    19     public static void foreach(Iterable<String> iterable) {
    20         for(String element : iterable) {
    21             System.out.println(element);
    22         }
    23     }
    24 }

      或者说,想要同时取得Map的键和值,我们可以使用entrySet()方法,这会返回一个Set对象,每个元素都是Map.Entry实例,可以调用getKey()取得键,调用getValue()取得值。看下面这段代码:

     1 package cc.openhome;
     2 
     3 import java.util.*;
     4 
     5 public class MapKeyValue2 {
     6     public static void main(String[] args) {
     7         Map<String, String> map = new TreeMap<>();
     8         map.put("one", "一");
     9         map.put("two", "二");
    10         map.put("three", "三");
    11         foreach(map.entrySet());
    12     }
    13     
    14     public static void foreach(Iterable<Map.Entry<String, String>> iterable) {
    15         for(Map.Entry<String, String> entry: iterable) {
    16             System.out.printf("(键 %s, 值 %s)%n", 
    17                     entry.getKey(), entry.getValue());
    18         }
    19     }
    20 }

    ——————————————————————————第二十天——————————————————————————

      紧赶慢赶,终于赶完了。

    1.今早妈妈给我打了个电话。我跟她说了我最近的情况。希望她能够明白,我最近过得很好,没有浪费大学仅剩不多的时间。

    2.关于误会,恐怕只有理解和沟通才能解开。就怕赌气,就怕错过能够解开的时机。

    3.昨晚还算有点怨气,到现在下午就已经慢慢没什么感觉了。我给自己最好的生日礼物就是,按照我希望的那样成长起来。

  • 相关阅读:
    [JavaScript]继续学习DOM事件模型
    [面试]作答整理一些面试题
    [JavaScript]使用jQuery实现无缝轮播
    [JavaScript]使用CSS + jQuery 实现自动轮播图
    [JavaScript]从DOM到jQuery(2)
    [JavaScript]从DOM到jQuery(1)
    [JavaScript]JavaScript中的函数(2)
    [JavaScript]JavaScript中的函数(1)
    [JavaScript]JavaScript中的Array
    React练习 7 :点击div,显示innerHTML
  • 原文地址:https://www.cnblogs.com/levenyes/p/3413062.html
Copyright © 2011-2022 走看看