目录
1.异常类
(1)什么是异常
程序运行是可能会出现一些错误,这就是异常。异常可以是人为规定的,比如自定义异常,也可以是一些基础的语法错误,数学错误(0除整数)等等。异常分为Error和Exception类,下方主要讨论Exception类。Error如果最后写完之前预习好了那就讨论下。
(2)常见的异常类
Exception有很多
子类,这里我们写其中一些很容易出现的异常类:
java.lang.NullPointerException(空指针类)
java.lang.ArithmeticException(数学运算异常)
java.lang.IndexOutOfBoundsException(下标越界)
java.lang.ClassCastException(类型转换异常)
//还有很多,我偷懒不想抄了等遇见了再积累。
(3)异常处理
在Java中,java.lang包中有Exception类,当出现一个异常时,就用throw关键字抛出一个Exception子类。比如下方情况:
源代码:
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 0;
int result = a / b;
System.out.println(result);
}
这里的运算出现了数学错误,0除整数。这在Java中会被当作异常,于是程序在第五行终止执行,抛出ArithmeticException对象。
Java使用try-catch语句处理异常
对于上面那个异常就可以使用try-catch语句来处里:
package com.bluemsun.mian;
public class test1Exception {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {
System.out.println(a/b);
}
catch (ArithmeticException e){
System.out.println("程序出现异常,变量b不能为0");
}
finally {
System.out.println("finally");
}
if(b == 0){
throw new ArithmeticException();
}
}
}
结果是:
try是用来检测a/b是否有异常的,如果语句有异常则进入catch,注意catch里面是(ArithmeticException e)如果异常类型正好是ArithmeticException那么执行catch里面的语句。一个try后面能接上很多catch检测各种类型的异常。最后的finally方法是无论是否有异常都会执行。在最后的if中,使用了throw关键字,抛出了ArithmeticException对象的异常信息。
ArithmeticException类是Exception的子类
点开后是这玩意,RuntimeException是它的父类。
2.常用类
(1)String类
String类在java.lang包中,java.lang包中的类被默认引入,所以程序可以直接使用String类。但要注意的是:String类被定义为final类,因此用户不能拓展出String的子类,即String不能有子类。
1)String类对象
常量对象:
String初始化的常量被称为常量对象,即用" "括起来的字符序列。常量对象创建后会被放入常量池,在常量池中,相同常量的引用是相同的。
package com.bluemsun.mian;
public class test2String {
public static void main(String[] args) {
String ni = "你";
String hao = "好";
String niHao = "你" + "好";
if(niHao == "你好"){
System.out.println(niHao);
}
}
}
String对象:
用String声明并创建对象
package com.bluemsun.mian;
public class test2String {
public static void main(String[] args) {
String a = new String("student");
String b = new String("student");
if(a == b){
System.out.println("student");
}
else{
System.out.println("no student");
}
}
}
结果是:
因为这里的a和b是String的引用,分别是代表一个指针,指向不同的空间,每个空间里都放有"student",如果直接比较a和b等同于比较它们存放"student"的地址,这肯定是不同的。
2)String类常用的方法
//有一说一,和c++很像,这些语言对字符串的处理都是差不多的
1 String(char a[])
将定义的一个字符数组转为String类型。
char a[] = {'j', 'a', 'v', 'a'};
String s = new String(a);
s就变成"java"了。
2 String (char a[], int startIndex,int count)
这个方法用来提取字符。(这里其实和c++中的substr(string s,int startindex, int count)很像)意思是:在字符数组a中,从下标startIndex开始,提取长度为count的字符,并转为字符串。
3 public boolean equals(String s)
使用时s.equals(s1)比较两个字符串是否相等,忽略大小写,返回值为boolean类型。
4 public int compareTo(String s)
使用时s.compareTo(s1),按照字典序比较大小,返回值为int类型,如果s > s1 则返回值为正数,相同返回值为0,小于返回值为负数。 根据返回值的正负,可以用来写一个排序。
5 public boolean contains(String s)
使用时s.contains(s1),s中如果有s1那么返回true,否则返回false。
6 public String substring(int start, int end)
使用时String str = s.substring(int start, int end),表示从s字符串的start位置到end - 1位置的字符串被提取出来,赋值给str,得到一个新的字符串。
7 public String toString()
使用时String str = s.toString(int t)可以将整数t转为String类型,当然不止int类型,其他很多类型的都可以转化。
上面这几个是个人认为比较常用的方法,其实还有其他的String类方法,就不一一举例了
(2)StringBuffer类
在上面的String的学习中,我发现String能执行的操作太少了,在一个String对象的字符序列中没办法执行修改,删除等操作,这简直太不方便了!!!于是我们就可以创建一个StringBuffer对象,它的实体的空间是动态的,可以自由改变大小。即StringBuffer类拓展了对字符序列的操作,同时具有动态内存,实体可变。
声明对象时的构造方法:
StringBuffer();
StringBuffer(String s);
StringBuffer(int t);
先介绍几个常用方法:
StringBuffer append(String s);
public char charAt(int n) ;
public void setCharAt(int n, char ch);
StringBuffer insert(int index, String s);
public StringBuffer reverse();
StringBuffer delete(int startIndex, int endIndex);
StringBuffer replace(int startIndex, int endIndex, String s);
这些方法该怎么用呢?看我写一串代码全用上它们!
package com.bluemsun.mian;
public class text3StringBuffer {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("nice to meet you!");
s.append("And you?");
System.out.println(s);
char getCh = s.charAt(16);
System.out.println(getCh);
s.setCharAt(0, 'N');
System.out.println(s);
StringBuffer str = new StringBuffer("!boB,iH");
s.insert(0, str);
System.out.println(s);
str.reverse();
System.out.println(str);
s.delete(0, 7);
s.insert(0, str);
System.out.println(s);
s.replace(3, 6, "Alice");
System.out.println(s);
}
}
非常的形象了,大家细细品味!!!!!!!!!!!!
(3)StringTokenizer类
这个类在java.util包中,可以使用StringTokenizer对象将一个String对象通过分隔标记符分为很多语言符号。
1)构造方法
StringTokenizer(String s):为String对象构造一个分析器,使用默认分隔符。
StringTokenizer (String s, String delim):为String对象构造一个分析器,delim中的字符任意排列作为分隔符。
2)常用方法
- 1. int countTokens():返回nextToken方法被调用的次数。
- 2. boolean hasMoreTokens():返回是否还有分隔符。返回值为1或0,3同。
- 3. boolean hasMoreElements():判断枚举 (Enumeration) 对象中是否还有数据。
- 4. String nextToken():返回从当前位置到下一个分隔符的字符串。
- 5. Object nextElement():返回枚举 (Enumeration) 对象的下一个元素。
- 6. String nextToken(String delim):与 4 类似,以指定的分隔符返回结果。
参考:菜鸟教程
注意:菜鸟教程第1个写得有歧义,这个返回的应该是nextToken还能被调用的次数,待会看我代码就行了。
用1,2,4,6写一串代码练练手:
package com.bluemsun.mian;
import java.util.StringTokenizer;
public class text3StringBuffer {
public static void main(String[] args) {
String s = "QQmian,is,a,handsome,男孩子";
StringTokenizer str = new StringTokenizer(s, ",");
String s2 = "QQm 是 一个 男孩子";
StringTokenizer str1 = new StringTokenizer(s2);
int cnt = 0;
while(str.hasMoreElements()){
cnt++;
System.out.println("nextToken还能被调用" + str.countTokens() + "次");
System.out.println(str.nextToken());
}
System.out.println("nextToken一共被调用了" + cnt + "次");
while(str1.hasMoreElements()){
System.out.println(str1.nextToken(" "));
}
}
}
输出结果:
nextToken还能被调用5次
QQmian
nextToken还能被调用4次
is
nextToken还能被调用3次
a
nextToken还能被调用2次
handsome
nextToken还能被调用1次
男孩子
nextToken一共被调用了5次
QQm
是
一个
男孩子
(4)Number & Math类
一般而言,在c和c++程序中我们都直接使用基本的数据类型定义的数据,而没有包装类这一说法(也可能是我还没学到)。在使用Java进行实际开发中,我们常常使用对象而非内置数据类型,int,double, float等等,Java为所有的内置数据类型都提供了对应的包装类。大致意思一应该是把某一个数据打包包装起来,使用时直接调用即可(使用时编译器拆包,不用时封装到包里,个人认为这种操作有效地提升了开发地安全性),这应该与Java的封装性有关。
1)Math类的一些方法
public static double abs(double num): 获取绝对值
public static double max(double a, double b):返回a,b的最大值
public static double min(double a, double b):返回a,b的最小值
public static double pow(double a, double b):返回a的b次幂
public static double sqrt(double a):返回a的平方根
public static double log(double a):返回值为自然对数为底数的对数值
public static double sin(double a):返回a的正弦值
public static double cos(double a):返回a的反正弦值
public static double ceil(double num): 向下取整
public static double floor(double num): 向上取整
public static long round(double num): 四舍五入注:Math.PI是Π
//还有很多很高级的玩意,以我的经验来看,现在用不上,反正也记不住,要用的时候再搜就行。
package com.bluemsun.mian;
public class operatorNumberMath {
public static void main(String[] args) {
System.out.println(Math.abs(-2));
System.out.println(Math.abs(2));
System.out.println(Math.pow(2.3, 2));
System.out.println(Math.sqrt(-2));
System.out.println(Math.sqrt(8));
System.out.println(Math.log(8));
System.out.println(Math.log(10));
System.out.println(Math.sin(Math.PI/4));
System.out.println(Math.cos(Math.PI/3));
System.out.println(Math.asin(1));
System.out.println(Math.max(-2, 4));
System.out.println(Math.min(-2, 4));
}
}
结果是:
2
2
5.289999999999999
NaN
2.8284271247461903
2.0794415416798357
2.302585092994046
0.7071067811865475
0.5000000000000001
1.5707963267948966
4
-2
//细心的小伙伴发现了,第四行出现了个NaN,因为-2不能开1/2次方所以输出了NaN。全称是Not a Number,而且请注意这里不是异常哦,并不会抛出异常。
3.容器
容器是能装对象的对象(其实很像stl),用来装对象以便统一管理,java中所有容器的根是collection接口。下面介绍三种常用容器:
(1)List
List集合特点是线性结构,长度可变,可存在重复。有ArrayList和LinkList,这两种操作是一样的,但是内部实现是不一样的,先通过代码看看ArrayList可执行的操作:
package com.bluemsun.mian;
import java.util.ArrayList;
import java.util.List;
public class test3List {
public static void main(String[] args) {
List list = new ArrayList();
list.add("你好");
list.add("你不好");
list.add("我不好");
list.add("大家都别好了!");
System.out.println(list);
list.remove("我不好");
System.out.println(list);
}
}
list.add()往尾部插入元素
list.remove()删除某个元素
ArrayList和LinkList的区别在于:
ArryList就是一个数组存储方式,查找效率高。
LinkList就是一个链表存储方式,查找效率低,但删除效率高。
对List的常用操作:
list.add()
List.remove()
List.size()
List.get(int index)得到object类型,有时候需要强制类型转换
List.contains()看看列表里是否有某个东西返回值为boolean类型
因为ArrayList和LinkList的接口都是List,所以这两个的操作是一样的。
(2)Set
set也是一个接口,特点是不允许重复数据的出现。Set可以声明两种对象HashSet和TreeSet。HashSet的特点是去重和乱序,TreeSet的特点是顺序和去重,也就是说他两之间的差别就在是否有序上。
常用操作:
add()添加元素
remove()删除元素
size()返回值为容器大小
contains()返回值为boolean类型,表示是否包含某个数据
package com.bluemsun.mian;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class test4Set {
public static void main(String[] args) {
Set s =new HashSet();
s.add("DFS");
s.add("TREE");
s.add("BFS");
s.add("BFS");
System.out.println(s);
System.out.println(s.size());
Set s2 = new TreeSet();
s2.add(2);
s2.add(9);
s2.add(1);
s2.add(0);
System.out.println(s2);
System.out.println(s2.size());
}
}
(3)Map
Map容器,它里面存储的对象是映射类型,存储两个对象,key和value,每一个key映射对应一个value。同样,Map里面有HashMap和TreeMap。HashMap是乱序的,而TreeMap是根据key来进行排序的。
常用操作:
put(key, value)如果加入的key在原map中有时,那么新的value会覆盖原value
remove(key)
size()
containsKey()
containsValue()
keySet()把key打包成set返回
get(key)通过key来查询value
package com.bluemsun.mian;
import javax.sound.midi.Soundbank;
import java.util.HashMap;
import java.util.Map;
public class test5Map {
public static void main(String[] args) {
Map map = new HashMap();
map.put("1", "QQmian");
map.put("a", "phy");
map.put("b", "hhh");
System.out.println(map);
System.out.println(map.size());
System.out.println(map.containsKey("1"));
System.out.println(map.containsValue("QQmian"));
System.out.println(map.get("a"));
System.out.println(map.keySet());
}
}
(4)Iterator(补充)
问题来了,在Set集合中,没有像 ArrayList那样的下标遍历,该如何遍历集合呢?用迭代器Iterator!!!迭代器从某种意义上来说就是指针,指向内存中特定空间的对象。话不多说,敲敲代码看看:
package com.bluemsun.mian;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
public class iter {
public static void main(String[] args) {
List list = new ArrayList();
list.add("QQmian");
list.add("nihao");
list.add("hello");
list.add("world");
Iterator it = list.iterator();
while(it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
}
}
}
next()返回指向的下一个对象,类型为object,所以有些时候要强制类型转换
haxNext()返回值为boolean,如果还有下一个对象则返回true否则返回false
迭代器有个特点,一但迭代取完集合内对象时,再取next()就会报错了。
用迭代器遍历map:
package com.bluemsun.mian;
import javax.sound.midi.Soundbank;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class test5Map {
public static void main(String[] args) {
Map map = new HashMap();
map.put("1", "QQmian");
map.put("a", "phy");
map.put("b", "hhh");
Set set = map.keySet();
Iterator it = set.iterator();
while(it.hasNext()){
String s = (String)it.next();
System.out.println(map.get(s));
}
}
}
4.泛型
用来规范容器的数据类型。比方在之前的例子中ArrayList对象里可以加任意int类型,String类型的对象,但是使用泛型规范后,ArrayList里面应该只能加某一类的对象。敲敲代码看看:
package com.bluemsun.mian;
import java.util.ArrayList;
import java.util.List;
public class test6Fan {
public static void main(String[] args) {
//泛型
List<String> strlist = new ArrayList<String>() ;
strlist.add("nihaoya");
strlist.add("hello");
strlist.add("你好");
String s = strlist.get(1);
System.out.println(s);
}
}
其实泛型还可以自己写:
package com.bluemsun.mian;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class test6Fan {
public static void main(String[] args) {
//泛型
List<people> list = new ArrayList<people>();
list.add(new people(1, "QQmian", 100));
list.add(new people(2, "QQmian", 101));
list.add(new people(3, "QQmian", 102));
System.out.println(list);
Iterator<people> it = list.iterator();
while(it.hasNext()){
people s = it.next();
System.out.println(s.getId() + " "+ s.getName() +" "+ s.getMoney());
}
}
}
package com.bluemsun.mian;
public class people {
private int id;
private String name;
private int money;
public int getId() {
return id;
}
public people(){
}
public people(int id, String name, int money) {
this.id = id;
this.name = name;
this.money = money;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
结果是:
这里第一排为什么会这样呢?因为我用people类规范了ArrayList对象,这里的list里面存的应该是对people的引用(可以把它当成指针来理解),所以要用迭代器来输出这些“引用”的值。同样,Map集合也可用泛型规范。不多说了。
终于结束了本周的预习博客,如有错误请大家指出,大家下周见!!!!