一、Map集合

1、java中的Map接口是和Collection接口同一等级的集合根接口,它表示一个键值对(key-value)的映射。

2、特点:即map集合是使用键(key)值(value)来保存数据,一次添加一对元素,称为双列集合,但键(key)必须唯一,也可为空,但最多只能有一个key为空,而且map集合必须保证键的唯一性(每个键最多映射一个值)。

3、常用方法:

添加:value put(key,value):返回前一个和key管理的值,如果没有返回null。

删除:void clear():清空map集合

根据指定的key翻出这个键值对。

判断:boolean containsKey(key):

            boolean containsValue(value):

            boolean isEmpty():

获取:Value get(key):通过键获取值,如果没有该键返回null,当然可以通过返回null来判断是否包含指定键int size():获取键值对的个数。

4、Map常用子类:

:内部结构是哈希表,是同步的,不允许null作为键,null作为值。

:内部是哈希表,不是同步的,允许null为键null为值。

:用来存储键值对型的配置文件信息,可以和IO技术相结合。

:内部结构是二叉树,不是同步的,可以对Map集合中的键进行排序。

5、取map中的元素时,

原理:通过keyset方法获取Map中所有键对应所在的set集合,在通过set集合中的迭代器获取每一个键,在对每一个键通过map集合中的get方法取对应的值。

通过map转换为set可以迭代。另一种方法就是 entryset,该方法将键和值的映射关系作为对象存到了set集合中,而这个映射关系类型就是Map.EntrySetl类型。

是Map中内部定义的一个接口,专门用来保存key value的内容。

6、代码示例:

package cn.itcast.p6.map.demo;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
method_2(map);
}
public static void method_2(Map<Integer,String> map){
map.put(8,"zhaoliu");
map.put(2,"zhaoliu");
map.put(7,"xiaoqiang");
map.put(6,"wangcai");
Collection<String> values = map.values();
Iterator<String> it2 = values.iterator();
while(it2.hasNext()){
System.out.println(it2.next());
}
/*

通过Map转成set就可以迭代。

找到了另一个方法。entrySet。

该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型(结婚证)

*/
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Integer, String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::::"+value);
}
//取出map中的所有元素。
//原理,通过keySet方法获取map中所有的键所在的Set集合,在通过Set的迭代器获取到每一个键,
//在对每一个键通过map集合的get方法获取其对应的值即可。
/*
Set<Integer> keySet = map.keySet();
Iterator<Integer> it = keySet.iterator(); 
while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println(key+":"+value); 
}
*/
}
public static void method(Map<Integer,String> map){//学号和姓名
// 添加元素。
System.out.println(map.put(8, "wangcai"));//null
System.out.println(map.put(8, "xiaoqiang"));//wangcai  存相同键,值会覆盖。
map.put(2,"zhangsan");
map.put(7,"zhaoliu");
//删除。
// System.out.println("remove:"+map.remove(2));
//判断。
// System.out.println("containskey:"+map.containsKey(7));
//获取。 
System.out.println("get:"+map.get(6));
System.out.println(map);
Outer.Inner.show();
}
}
interface MyMap{
public static interface MyEntry{//内部接口
void get();
}
}
class MyDemo implements MyMap.MyEntry{
public void get(){}
}
class Outer{
static class Inner{
static void show(){}
}
}

7、Comparator接口的使用

使用Comparable接口定义排序顺序有局限性:实现此接口的类只能按compareTo()定义的这一种方式排序。

如果同一类对象要有多种排序方式,应该为该类定义不同的比较器(实现Comparator接口的类)TreeSet有一个构造方法允许给定比较器,它就会根据给定的比较器对元素进行排序.

Comparator接口中的比较方法:

public int compare(Object o1, Object o2); 该方法如果

返回 0,表示 o1 == o2

返回正数,表示

返回负数,表示

代码示例:

package cn.itcast.p2.bean;
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int compareTo(Person p){
// Person p = (Person)obj;
int temp = this.age - p.age;
return temp==0?this.name.compareTo(p.name):temp;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person:"+getName()+":"+getAge();
}
}
package cn.itcast.p2.bean;
public class Student extends Person {
public Student() {
super(); 
}
public Student(String name, int age) {
super(name, age);
}
@Override
public String toString() {
return "Student:"+getName()+":"+getAge();
}
}
package cn.itcast.p2.bean;
public class Worker extends Person {
public Worker() {
super();
}
public Worker(String name, int age) {
super(name, age);
}
@Override
public String toString() {
return "Worker:"+getName()+":"+getAge();
} 
}
package cn.itcast.p3.comparator;
import java.util.Comparator;
import cn.itcast.p2.bean.Person;
public class ComparatorByName implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
int temp = o1.getName().compareTo(o2.getName());
return temp==0? o1.getAge()-o2.getAge(): temp;
}
}

二、异常机制

1、异常

异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序

2、异常分类

   

3、在java中用类的形式对不正常情况进行了描述和封装对象。

描述不正常的情况的类,就称为异常类。

以前正常流程代码和问题处理代码相结合,

现在将正常流程代码和问题处理代码分离。提高阅读性.

其实异常就是java通过面向对象的思想将问题封装成了对象.

用异常类对其进行描述。

不同的问题用不同的类进行具体的描述。 比如角标越界。空指针等等。

问题很多,意味着描述的类也很多,

将其共性进行向上抽取,形成了异常体系。

4、java异常处理通过5个关键字来实现:

、catch、 finally、throw、throws

5、最终问题(不正常情况)就分成了两大类。

无论是error,还是异常,问题,问题发生就应该可以抛出,让调用者知道并处理。

//该体系的特点就在于Throwable及其所有的子类都具  有可抛性。

可抛性到底指的是什么呢?怎么体现可抛性呢?

其实是通过两个关键字来体现的。

throws throw ,凡是可以被这两个关键字所操作的类和对象都具备可抛性.

|--1,一般不可处理的。Error

特点:是由jvm抛出的严重性的问题。

这种问题发生一般不针对性处理。直接修改程序

|--2,可以处理的。Exception

该体系的特点:

子类的后缀名都是用其父类名作为后缀,阅读性很想。

*/
class ExceptionDemo 
{
public static void main(String[] args) 
{
int[] arr = new int[1024*1024*800];//java.lang.OutOfMemoryError: Java heap space
// arr = null;
// System.out.println(arr[3]);
//
//
// sleep(-5);
}
 
 
public static void sleep2(int time)
{
if(time<0)
{
// 处理办法。
// 处理办法。
// 处理办法。
// 处理办法。
// 处理办法。
}
if(time>100000)
{
// 处理办法。
// 处理办法。
// 处理办法。
// 处理办法。
// 处理办法。
// 处理办法。
}
System.out.println("我睡。。。"+time);
 
// sleep(-5);
}
public static void sleep(int time)
{
if(time<0)
{
// 抛出 new FuTime();//就代码着时间为负的情况,这个对象中会包含着问题的名称,信息,位置等信息。
}
if(time>100000)
{
// 抛出
}
System.out.println("我睡。。。"+time);
}
}
/*
class FuTime
{
}
class BigTime
{
}
*/

4、异常的分类

1,编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。

这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。

这样的问题都可以针对性的处理。

2,编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类。

这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致的而或者引发了内部状态的改变导致的。

那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行修正。

所以自定义异常时,要么继承Exception。要么继承RuntimeException。

5、异常处理机制原理

程序在执行过程中如果出现异常,会自动生成一个异常类对象,该异常对象将被自动提交给JVM(在程序没有显式处理异常的情况下),这个过程称为抛出(throw)异常。

6、异常的注意事项:

,子类在覆盖父类方法时,父类的方法如果抛出了异常,

那么子类的方法只能抛出父类的异常或者该异常的子类。

2,如果父类抛出多个异常,那么子类只能抛出父类异常的子集。

 

简单说:子类覆盖父类只能抛出父类的异常或者子类或者子集。

注意:如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛,就只能try .

代码示例:

interface  Inter
{
            void function();
}
 
class D implements Inter
{
         public void function()//throws Exception
          {}
}
 
 
class A extends Exception 
{
}
class B extends A
{
}
class C extends Exception 
{
}
Exception
  |--A
  |--B
  |--C
class Fu
{
  void show()throws A
  {}
}
class Test
{
  void method(Fu f)//Fu f  = new Zi();
  {
  try
   {
  f.show();
   }
   catch (A  a)
   {
    }
      }
}
class Zi extends Fu
{
      void show()throws C
    {
     }
}
class  
{
    public static void main(String[] args) 
    {
    Test t = new Test();
    t.show(new Zi());
     }
}

7、自定义异常

对于角标是整数不存在,可以用角标越界表示,

对于负数为角标的情况,准备用负数角标异常来表示。

负数角标这种异常在java中并没有定义过。

那就按照java异常的创建思想,面向对象,将负数角标进行自定义描述。并封装成对象。

这种自定义的问题描述成为自定义异常。

注意:如果让一个类称为异常类,必须要继承异常体系,因为只有称为异常体系的子类才有资格具备可抛性。

才可以被两个关键字所操作,throws throw