Java学习总结(六)——(Map集合,Comparator接口,异常等)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java学习总结(六)——(Map集合,Comparator接口,异常等),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含16219字,纯文字阅读大概需要24分钟。
内容图文
一.Comparator接口*Comparator接口的使用
(1)使用Comparable接口定义排序顺序有局限性:实现此接口的类只能按compareTo()定义的这一种方式排序。
(2)如果同一类对象要有多种排序方式,应该为该类定义不同的比较器(实现Comparator接口的类)TreeSet有一个构造方法允许给定比较器,它就会根据给定的比较器对元素进行排序.
(3)Comparator接口中的比较方法
示例: public int compare(Object o1, Object o2);
该方法如果
返回 0,表示 o1 == o2
返回正数,表示 o1 > o2
返回负数,表示 o1 < o2
例(以学生成绩排名为例):
学生类(Student):
package comparator;
public class Student {
private String name ;
private int score ; //总分
private int math ; //语文成绩
public Student() {
super ();
}
public Student(String name , int score , int math ) {
super ();
this . name = name ;
this . score = score ;
this . math = math ;
}
public String getName() {
return name ;
}
public void setName(String name ) {
this . name = name ;
}
public int getScore() {
return score ;
}
public void setScore( int score ) {
this . score = score ;
}
public int getMath() {
return math ;
}
public void setMath( int math ) {
this . math = math ;
}
@Override
public String toString() {
return "Student [name=" + name + ", score=" + score + ", math=" + math
+ "]" ;
}
}
以总分为第一排序准则类( ScoreRule ):
package comparator;
import java.util.*;
public class ScoreRule implements Comparator<Student> {
@Override
public int compare(Student stu1 , Student stu2 ) {
if ( stu1 .getScore()> stu2 .getScore()){
return -1;
} else if ( stu1 .getScore()< stu2 .getScore()){
return 1;
} else {
if ( stu1 .getMath()> stu2 .getMath()){
return -1;
} else if ( stu1 .getMath()< stu2 .getMath()){
return 1;
} else {
return stu1 .getName().compareTo( stu2 .getName());
}
}
}
}
以数学成绩为第一标准排序类(MathRule):
package comparator;
import java.util.Comparator;
public class MathRule implements Comparator<Student>{
@Override
public int compare(Student stu1 , Student stu2 ) {
if ( stu1 .getMath()> stu2 .getMath()){
return -1;
} else if ( stu1 .getMath()< stu2 .getMath()){
return 1;
} else {
if ( stu1 .getScore()> stu2 .getScore()){
return -1;
} else if ( stu1 .getScore()< stu2 .getScore()){
return 1;
} else {
return stu1 .getName().compareTo( stu2 .getName());
}
}
}
}
测试TreeSet类:
package comparator;
import java.util.TreeSet;
public class TestSetDemo {
public static void main(String[] args ) {
TreeSet<Student> set = new TreeSet<Student>( new ScoreRule());
set .add( new Student( "独孤求败" ,786,145));
set .add( new Student( "王磊" ,456,78));
set.add(new Student("王忠磊",564,97));
set.add(new Student("风清扬",786,123));
set.add(new Student("王磊",456,78));
set.add(new Student("王磊",456,78));
set.add(new Student("杨过",456,98));
set.add(new Student("令狐冲",556,86));
set.add(new Student("张无忌",665,100));
set.add(new Student("独孤求败",786,145));
set.add(new Student("孙悟空",754,147));
set.add(new Student("唐僧",453,67));
System.out.println("以总分为 排序第一标准:");
for (Student stu : set ){
System. out .println( stu );
}
System. out .println();
TreeSet<Student> set1=new TreeSet<Student>(new MathRule());
set1.add(new Student("独孤求败",786,145));
set1.add(new Student("王磊",456,78));
set1.add(new Student("王忠磊",564,97));
set1.add(new Student("风清扬",786,123));
set1.add(new Student("王磊",456,78));
set1.add(new Student("王磊",456,78));
set1.add(new Student("杨过",456,98));
set1.add(new Student("令狐冲",556,86));
set1.add(new Student("张无忌",665,100));
set1.add(new Student("独孤求败",786,145));
set1.add(new Student("孙悟空",754,147));
set1.add(new Student("唐僧",453,67));
System.out.println("以数学成绩为第一排序标准:");
for(Student stu:set1){
System.out.println(stu);
}
}
}
运行结果为:
以总分为排序第一标准:
Student [name=独孤求败, score=786, math=145]
Student [name=风清扬, score=786, math=123]
Student [name=孙悟空, score=754, math=147]
Student [name=张无忌, score=665, math=100]
Student [name=王忠磊, score=564, math=97]
Student [name=令狐冲, score=556, math=86]
Student [name=杨过, score=456, math=98]
Student [name=王磊, score=456, math=78]
Student [name=唐僧, score=453, math=67]
以数学成绩为第一排序标准:
Student [name=孙悟空, score=754, math=147]
Student [name=独孤求败, score=786, math=145]
Student [name=风清扬, score=786, math=123]
Student [name=张无忌, score=665, math=100]
Student [name=杨过, score=456, math=98]
Student [name=王忠磊, score=564, math=97]
Student [name=令狐冲, score=556, math=86]
Student [name=王磊, score=456, math=78]
Student [name=唐僧, score=453, math=67]
分析:例中分别以学生的总分和数学分数为第一标准进行了排序,属于同一对象多种排序,故我们实现了Comparator接口实现了接口中的public int compare(Object o1, Object o2)方法,分别制定了各种排序得规则(即比较器),TreeSet中的构造方法允许给定比较器,按照比较器进行排序。
二.Map集合
1.特点:
(1)实现Map接口的集合类用来存储“键-值”映射对。
(2)不能包含重复的键,每个键最多只能映射到一个值,值可以重复。
(3)JDK API中Map接口的实现类常用的有:
HashMap
TreeMap
Hashtable (不常用)
Properties
2.Map接口中的常用方法:
(1)Object put(Object key, Object value); //将指定的“键-值”对存入Map中
(2)Object get(Object key); //返回指定键所映射的值
(3)Object remove(Object key); //根据指定的键把此“键-值”对从Map中移除。
(4)boolean containsKey(Object key); //判断此Map是否包含指定键的“键-值”对。
(5)boolean containsValue(Object value); //判断此Map是否包含指定值的“键-值”对。
(6)boolean isEmpty(); //判断此Map中是否有元素。
(7)int size(); //获得些Map中“键-值”对的数量。
(8)void clear(); //清空Map中的所有“键-值”对。
(9)Set keySet(); //返回此Map中包含的键的Set集。
(10)Collection values(); //返回此Map中包含的值的Collection集。
(11)Set<Map.Entry<K,V>> entrySet() 将所有包含键-值对的Map.Entry收集到Set
3.Map.Entry接口:
*Map.Entry是Map中内部定义的一个接口,专门用来保存key value的内容。
4.HashMap类与TreeMap类
(1)HashMap存储结构使用哈希表,使用“键”进行散列存放。所以根据“键”去 取“值”的效率很高 。
(2)TreeMap中的“key-value”对的“key”必须是 可“排序” 的。
5.HashTable类
(1)旧版的Hashtable,操作大多跟HashMap相同,只是它保证线程的同步。
(2)它有一个子类Properties(属性集)比较常用:
*Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性集中 每个键及其对应值都是一个字符串 。
*不建议使用 put 和 putAll 这类存放元素方法,应该使用 setProperty(String key, String value) 方法,因为存放的“键-值”对都是字符串。类似取值也应该使用 getProperty(String key) 。
例(以Properties类举例):
package mapdemo;
import java.util.Properties;
public class PropertiesDemo {
public static void main(String[] args ) {
Properties pro = new Properties();
pro .setProperty( "张三丰" , "149岁" );
pro .setProperty( "奥运会" , "08中国" );
pro .setProperty( "游泳冠军" , "孙杨" );
pro .setProperty( "六脉神剑" , "段誉" );
pro .setProperty( "降龙十八掌" , "郭靖" );
System. out .println( "根据键找到对应的值:" + pro .getProperty( "奥运会" ));
System. out .println( pro .getProperty( "游泳冠军" , " " ));
System. out .println( pro .getProperty( "iguihejg" , "没有 找到对应的值,这是默认值~~~ " ));
}
}
运行结果为:
根据键找到对应的值:08中国
孙杨
没有 找到对应的值,这是默认值~~~
-
HashMap和Hashtable区别:
(1) HashMap不同步,Hashtable同步
(2) HashMap可以存储null键null值,Hashtable不可以
(3) HashMap多线程操作环境下效率高,Hashtable多线程操作环境下效率低
例(以Map集合及其常用方法为例):
package mapdemo;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args ) {
HashMap<String, String> map = new HashMap<>();
map .put( "country" , "中国" );
map .put( "name" , "令狐冲" );
map .put( "apple" , "苹果" );
map .put( "banana" , "香蕉" );
map .put( "sing" , "唱歌" );
map .put( "map" , "集合" );
System. out .println( "原始集合键值对数:" + map .size());
System. out .println( "集合中以country为Key的键值是:" + map .get( "country" ));
map .remove( "name" ); //移除name键值对
System. out .println( "移除name集合中以name为Key的键值是:" + map .get( "name" ));
System. out .println( "现在集合键值对数:" + map .size());
System. out .println( "集合中包括key是banana的键值对吗? " + map .containsKey( "banana" ));
System. out .println( "集合中包括value是苹果的键值对吗? " + map .containsValue( "苹果" ));
Set<String> set = map .keySet();
System. out .println( "获取集合中所有的key,遍厉得:" );
for (String str : set ){
System. out .print( str + " " );
}
System. out .println();
System. out .println( "获取集合中所有的value值,并遍厉得:" );
Collection<String> set1 = map .values();
for (String str : set1 ){
System. out .print( str + "\t" );
}
System. out .println();
System. out .println( "**********遍厉集合中的所有键值对*********" );
Set<Map.Entry<String, String>> setEntry = map .entrySet();
for (Map.Entry<String, String> ma : setEntry ){
System. out .println( ma .getKey()+ "========>" + ma .getValue());
}
}
}
运行结果为:
原始集合键值对数:6
集合中以country为Key的键值是:中国
移除name集合中以name为Key的键值是:null
现在集合键值对数:5
集合中包括key是banana的键值对吗? true
集合中包括value是苹果的键值对吗? true
获取集合中所有的key,遍厉得:
banana country apple sing map
获取集合中所有的value值,并遍厉得:
香蕉 中国 苹果 唱歌 集合
**********遍厉集合中的所有键值对*********
banana========>香蕉
country========>中国
apple========>苹果
sing========>唱歌
map========>集合
三.异常机制
-
异常的概念:异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
-
Java中如何进行异常处理:Java的异常处理是通过5个关键字来实现的:
(1)try执行可能产生异常的代码
(2)Catch捕获异常
(3)Finally无论是否产生异常总能执行的代码
*其上三个 关键字 都属于捕获异常的范畴
(4)throws声明方法可能要抛出的各种异常
*throws属于声明异常
(5)Throw手动跑出异常对象
*throw属于抛出异常
3.Java程序编译和运行时所发生的问题有两大类:
(1)错误(Error):JVM系统内部错误或资源耗尽等严重情况-属于JVM需要负担的责任
(2)异常(Exception):其它因编程错误或偶然的外在因素导致的一般性问题。
*程序员只能处理异常而对错误无能为力
4.异常处理机制的原理:Java程序在执行过程中如果出现异常,会自动生成一个异常类对象,该异常类对象将被自动提交给JVM(在程序没有显式处理异常的情下),这个过程称为抛出异常(throw)
5.异常的分类:
(1)检查时异常(E xception):SQLException,
IOException,
ClassNotFoundException,
......
例(检查时异常):
package exceptiondemo;
import java.io.IOException;
public class CheckExceptionDemo {
public static void main(String[] args ) {
Runtime run =Runtime. getRuntime ();
try {
run . exec ( "clac" ) ;
} catch ( IOException e ) {
System. out .println( e .getMessage());
}
}
}
运行结果为:
Cannot run program "clac": CreateProcess error=2, 系统找不到指定的文件。
(2)运行时异常(RunTimeException):NullPointerException,
ArithmeticExcepttion,
ClassCastExceptioion,
ArrayIndexOutOfBundsException,
.......
(3)常见异常:( RunTimeException )
ArithmeticException:数学计算异常
NullPointerException:空指针异常
ArrayOutOfBoundsException:数组索引越界异常
ClassCastException:类型转换异常
6.Exception与RuntimeException
(1)Exception在程序中是必须进行处理
(2)RuntimeException可以不使用try…catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。
7.处理异常的方法:
*使用try-catch块捕获异常,catch块可以有多个
格式如下:
public void method(){
try {
// 代码段(此处可能产生异常)
} catch (异常类型 ex) {
// 对异常进行处理的代码段
}
// 代码段
}
例(以0作为除数为例):
package exceptiondemo;
public class TryCatchDemo {
public static void main(String[] args ) {
try {
int a =99;
int b =0;
int temp = a / b ;
} catch (Exception e ) {
System. out .println( "产生异常了~~~" );
System. out .println( "输出捕获道德异常" + e .getMessage());
}
System. out .println( "程序继续向下运行!!。。。。" );
}
}
运行结果为:
产生异常了~~~
输出捕获道德异常/ by zero
程序继续向下运行!!。。。。
8.常见的异常类型:
异常类型 |
说明 |
Exception |
异常层次结构的父类 |
ArithmeticException |
算数错误情形,如以0作除数 |
ArrayIndexOutOfBoundsException |
数组下标越界 |
NullPointerException |
尝试访问null对象成员 |
ClassNotFoundException |
不能加载所需的类 |
IllegalArgumentException |
方法接收到非法参数 |
ClassCastException |
对象强制类型转换出错 |
NumberFormatException |
数字格式转换异常,例“abc”转换成数字 |
9.try--catch--finally:
(1)在try--catch模块后加上finally代码块,无论是否发生异常,finally中的代码都会执行
(2)有一种情况例外:在try--cathch块后加了System.exit(0),会直接关闭JVM
例(还是以0作除数为例):
package exceptiondemo;
public class FinallyDemo {
public static void main(String[] args ) {
try {
int result = divide (99,0);
System. out .println( "计算结果为:" + result );
} catch (Exception e ) {
System. out .println( "出现异常了~~~~" );
System. out .println( "输出异常信息:" + e .getMessage());
} finally {
System. out .println( "进入finally块程序继续运行:" );
int x =1;
int y =1;
int temp = x + y ;
System. out .println( "计算结果为:" + temp );
}
System. out .println( "进入主方法程序继续向下运行!!!!!!" );
}
public static int divide( int x , int y ){
int result = x / y ;
return result ;
}
}
运行结果为:
出现异常了~~~~
输出异常信息:/ by zero
进入finally块程序继续运行:
计算结果为:2
进入主方法程序继续向下运行!!!!!!
10.多重catch块(引发多种类型的异常):
(1)排列catch块语句顺序:先子类后父类
(2)发生异常时按顺序逐个匹配
(3)只执行第一个与异常类型匹配的catch语句
格式:
public void method(){
try {
// 代码段
// 产生异常(异常类型2)
} catch (异常类型1 ex) {
// 对异常进行处理的代码段
} catch (异常类型2 ex) {
// 对异常进行处理的代码段
} catch (异常类型3 ex) {
// 对异常进行处理的代码段
}
// 代码段
}
例(挨个捕捉异常):
package exception;
public class RuntimeExceptionDemo {
public static void main(String[] args ) {
int a =100;
int b =0;
String str = null ;
int [] array = new int [5];
try {
array [5]=100;
str .equals( "abc" );
int c = a / b ;
} catch (NullPointerException e ){
System. out .println( "空指针异常~~~" );
} catch (ArithmeticException e ){
System. out .println( "算数异常~~~" );
} catch (Exception e ){
System. out .println( "以上catch都没有捕获到异常,由最大父类Exception处理异常" );
} finally {
System. out .println( " 进入 finally块 无论异常是否发生,都会执行" );
}
System. out .println( "main()方法执行完毕!" );
}
}
运行结果为:
以上catch都没有捕获到异常,由最大父类Exception处理异常
进入 finally块 无论异常是否发生,都会执行
main()方法执行完毕!
11.try---finally:try…finally 不能捕获异常 ,仅仅用来当发生异常时,用来释放资源
格式:
public void method(){
try {
// 代码段 1
// 产生异常的代码段 2
}finally{
// 代码段 3
}
}
例(以0作除数为例):
package exceptiondemo;
public class TryFinallyDemo {
public static void main(String[] args ) {
try {
int x =88;
int y =0;
int temp = x / y ;
System. out .println( "计算结果为:" + temp );
} finally {
System. out .println( "用于释放资源" );
}
}
}
运行结果为:
用于释放资源
Exception in thread "main" java.lang.ArithmeticException : / by zero
at exceptiondemo.TryFinallyDemo.main( TryFinallyDemo.java:9 )
由结果可知 try--finally不会捕获异常,只用于释放资源
12.throw与throws的区别:
(1)throw用来手动抛出异常
(2)Throws用于方法声明处,用于抛出该方法体内部可能发生的异常类型。一旦在方法声明处通过throws抛出某种类型的异常,则在该方 法体内部就不用处理该类型的异常,交给方法调用处处理该类型的异常。
例1(手动抛出异常):
package throwdemo;
public class ThrowDemo {
public static void main(String[] args ) {
try {
int [] a = new int [3];
System. out .println( a [4]);
// throw new ArrayIndexOutOfBoundsException();
} catch (Exception e ) {
System. out .println( "发生了数组越界异常~~~" );
}
}
}
运行结果为:
发生了数组越界异常~~~
例2(throws声明异常):
package throwsdemo;
public class ThrowsDemo {
public static void main(String[] args ) {
try {
int result = divide (88,2);
System. out .println( "计算结果为:" + result );
} catch (Exception e ) {
System. out .println( e .getMessage());
e .printStackTrace();
}
}
public static int divide( int x , int y ) throws Exception{
int result = x / y ;
return result ;
}
}
运行结果为:
计算结果为:44
*注意在调用异常声明方法是,如果不知道如何处理异常,也可使用throw关键字继续将异常抛出,这样程序也可以编译通过,但程序一旦发生异常,如果程序没有被处理,程序就会非正常终止
例:
package throwsdemo;
public class ThrowsDemo01 {
public static void main(String[] args ) throws Exception {
int result = divide (88,0);
System. out .println( "计算结果为:" + result );
}
public static int divide( int x , int y ) throws Exception{
int result = x / y ;
return result ;
}
}
运行结果为:
Exception in thread "main" java.lang.ArithmeticException : / by zero
at throwsdemo.ThrowsDemo01.divide( ThrowsDemo01.java:10 )
at throwsdemo.ThrowsDemo01.main( ThrowsDemo01.java:6 )
13.自定义异常:
(1)创建自定义异常:继承自Exception 。习惯上包装一下父类的构造方法。
格式:
public class MyException extends Exception {
public MyException() {
super();
}
public MyException(String msg) {
super(msg);
}
}
(2)使用自定义异常:
格式:
public String[] createArray(int length) throws MyException {
if (length < 0) {
throw new MyException("数组长度小于0,不合法");
}
return new String[length];
}
例1(以上述自定义异常和使用自定义异常为例):
自定义异常类(继承父类Exception):
package throwexception;
public class DivideByMinusException extends Exception{
public DivideByMinusException(){
super ();
}
public DivideByMinusException(String message ){
super ( message );
}
}
测试自定义异常类:
package throwexception;
public class ThrowExceptionDemo {
public static void main(String[] args ) {
try {
int result = divide (55,-5);
System. out .println( "计算结果为:" + result );
} catch (DivideByMinusException e ) {
System. out .println( e .getMessage());
}
}
public static int divide( int x , int y ) throws DivideByMinusException{
if ( y <0){
throw new DivideByMinusException( "被除数是负数~~~" );
}
int result = x / y ;
return result ;
}
}
运行结果为:
被除数是负数~~~
例2(以货船载货为例自定义异常):
自定义LoadException异常:
package boat;
public class LoadException extends Exception{
public LoadException(){
super ();
}
public LoadException(String message ){
super ( message );
}
}
货船模拟装货类:
package boat;
public class Boat {
private static final int MAX_STORE =1000;
private int currentStore ;
public void load( int num ) throws LoadException{
System. out .println( "货船装货前当前载货量:" + currentStore );
currentStore += currentStore ; //模拟装货
System. out .println( "货船装货后的当前载货量:" + currentStore );
if ( currentStore > MAX_STORE ){
System. out .println( "已超载,货船面临乘船危险~~" );
}
}
}
测试货船装货类:
package boat;
import java.util.Scanner;
public class TestBoat {
public static void main(String[] args ) {
Boat bo = new Boat();
while ( true ){
Scanner scan = new Scanner(System. in );
System. out .print( "请输入要载入载货量:" );
int cur = scan .nextInt();
try {
bo .load( cur );
} catch (LoadException e ) {
System. out .println( "输出 捕获的异常:" + e .getMessage());
break ;
}
scan .close();
}
}
}
* 小结( finally 易错点):
例:
package easyeorror;
public class FinallyDemo {
public static void main(String[] args ) {
int result = divide (4,6);
System. out .println( "所返回 的结果是:" + result );
}
public static int divide( int x , int y ){
try {
int temp = x + y ;
return temp ;
} catch (Exception e ) {
System. out .println( "发生异常了~~~~~~~" );
} finally {
int result = x * y ;
return result ;
}
}
}
运行结果为:
所返回 的结果是:24
【本次总结完毕】
2018.1.12
原文:http://blog.51cto.com/13501268/2060694
内容总结
以上是互联网集市为您收集整理的Java学习总结(六)——(Map集合,Comparator接口,异常等)全部内容,希望文章能够帮你解决Java学习总结(六)——(Map集合,Comparator接口,异常等)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。