博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
渣渣小本求职复习之路每天一博客系列——Java基础(6)
阅读量:5305 次
发布时间:2019-06-14

本文共 9160 字,大约阅读时间需要 30 分钟。

  前情回顾:上一篇除了回顾了异常处理的后半部分之外,还进行了对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     @Override17     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     @Override17     public String toString() {18         return String.format("Account2(%s, %s, %d)", name, number, balance);19     }20 21     @Override22     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
{ 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
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
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
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
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
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
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
> iterable) {15 for(Map.Entry
entry: iterable) {16 System.out.printf("(键 %s, 值 %s)%n", 17 entry.getKey(), entry.getValue());18 }19 }20 }

 

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

  紧赶慢赶,终于赶完了。

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

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

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

转载于:https://www.cnblogs.com/levenyes/p/3413062.html

你可能感兴趣的文章
算法 数位DP(按位DP) hdoj 2089 hdoj 3555 uestc 1307 基础题
查看>>
OC语言构造方法
查看>>
Java 8新特性-4 方法引用
查看>>
多线程技术中生产者和消费者简单模拟实现
查看>>
上传jar包到nexus私服
查看>>
nginx error_page 404 用 php header 无法跳转
查看>>
Java多线程和并发基础
查看>>
CodeForces - 55D Beautiful numbers
查看>>
PHP CURL错误: error:140943FC
查看>>
array_combine
查看>>
[LeetCode-124] Binary Tree Maximum Path Sum
查看>>
使用JDK的zip编写打包工具类
查看>>
基于FPGA的前向纠错算法
查看>>
Python装饰器(1)
查看>>
mysql 分页查询
查看>>
金蝶数据库开发,采购订单生成收料通知单影响哪些表
查看>>
Handler没法取出消息队列中的数据的一个原因
查看>>
给 C# 中的 Guid 扩展一个 TryParse 方法
查看>>
C指针-const char* p到底是什么不可以改变
查看>>
TextField 、 FTE、 TLF 的使用情景和简单说明
查看>>