这段时间在看JAVA是从菜鸟教程上总结的有不足或者错误的地方望指出,内容纯手打.
目前在看JAVA编程思想,届时也会总结一份分享出来.
一.JAVA基础
1.枚举
enum DogSize{
SMALL,MIDDLE,BIG
}
2.JAVA特性
引用:
String s;//我创建了一个引用
s = “haha”;//这个引用指向的是”haha”这个对象
特性:继承,多态,封装,抽象,类,对象,实例,方法,消息解析
3.构造方法
构造方法的名称必须和类名一致,一个类中可以有多个构造方法,构造方法可以传值
举个🌰
public class Dog{
//这是构造方法
public Dog(){
}
//这也是构造方法而且能共存,只不过加了参数
public Dog(String name){
}
}
4.实例化
使用new实例化对象(放在堆里)
Dog dog = new Dog();
Dog dog = new Dog(“参数”);
5.调用方法和参数使用点语法,参数直接点就可以,方法在后面需要加();
注意的地方
(1)一个源文件可以有多个class类但是只能有一个public class,源文件名需要和public 类名保持一致,否则使用时需要指定非public class才可以使用
(2)如果类定义在package中,那么package 包名必须在class源文件的第一行,import的类在package下面
举例包和类的引用
所在包的包名:package 包名
类的引用:
类在包中:import 包名.类名
类不再包中:import 类名
6.数据类型
int float double short long
常量:final double PI = 3.14;
字符:’’
字符串:””
变量定义与C类似
int a,b,c;
Int d=0,f,g=1;
7.变量类型
类变量(静态变量)
使用static修饰,但是很少单独使用static修饰,一般都是搭配final修饰常量.静态变量存储在静态存储区一旦创建不会消失,直到程序结束.类变量被声明成为public static final时命名必须全为大写字母,其他情况正常命名方式,public static final PI
局部变量不能被修饰为static变量
8.访问修饰符(修饰类的初始话方法)
Default:同一个包内可见,默认的不使用修饰符.
Private:私有的只能在当前类中访问,子类也不能访问.
Public:共有的,所有类都可以访问.
Protected:受保护的只在同一个包内的类和子类可见.
(1)父类中修饰为public的方法子类中也必须为public
(2)父类中修饰为private的方法子类中不能继承
(3)父类中修饰为protected的方法子类只能用public或者protected修饰
9.非访问修饰符
Static用来修饰类方法和类变量,不能修饰类(被static修饰的方法就是类方法)
Final:修饰方法,变量和类 ,final修饰的类不能被继承,final修饰的方法不能被子类重定义,变量不能修改
Abstrct:用了创建抽象类和抽象方法
Synchronize和Volatile主要用来修饰多线程的
10.抽象(abstract)
抽象类中可以有构造方法,但是只是不能被创建对象.而且抽象类写了构造方法子类必须得实现构造方法,而且还得显式的调用super();
抽象方法是没有任何实现的方法
抽象方法是没有任何实现的方法,但是抽象类中可以有方法的实现,这个方法不是抽象方法就可以
抽象方法不能被声明为final和static
继承抽象类的子类必须实现抽象类的所有抽象方法,除非子类本身是抽象类
11.进制转换
十进制转二进制
取余倒叙,一直到商小于1
举例
13/2 = 6余1
6/2 = 3余0
3/2 = 1余1
1/2 = 0 余1
结果过为1101
二进制转十进制
举例
1101.0101
整数部分和小数部分分开,整数部分从右向左转换,小数部分从左向右开始转换(整数部分的幂从0开始,
小数部分从-1开始)
1*2^0+0*2^1+1*2^2+1*2^3+0*2^(-1)+1*2^(-2) + 0*2^(-3) + 1*2^(-4)
1+0+4+8+0+0.25+0+0.0625 = 13.3125
其他的进制转换一样的道理,唯一变化的是2变8变16而已
11.位运算
a=60 二进制为0011 1100
b=13 二进制为0000 1101
`位数不够时在左侧补0`
& 按位与操作符:当二进制位上两位都为1的值该位上的值为1,a&b = 0000 1100 = 12
| 按位或操作符:当二进制位上有一位为1该位上的值为1 , a|b = 0011 1101 = 61
^ 按位异或操作符:当二进制位上两位不相同时该位结果为1,a^b = 0011 0001 = 49
~ 按位补运算符:翻转操作符上的每一位,~a = 1100 0011 = -60
<<按位左移运算符:左操作数按位左移右操作数指定的位数(右侧位移动得到的空位补0),
a<<2 = 1111 0000 =240
>>按位右运算符:左操作数按位右移右操作数指定的位数(不补0),a>>2 = 0011 11 = 15
>>>按位右移补零操作符:左操作数按位右移右操作数指定的位数移动得到的左侧空位以0补充,a>>>2 = 0000 1111 = 15
12.运算符
instanceOf运算符判断变量是否属于某个类型
举例:
String name = “董”;
boolean result = name instanceOf String;(中间没有点)
Result 为真
13.循环(新的循环类似for in)
int [] arr = {10,20,30};
for(int m : arr){
}
14.Number和Math
常见使用方法
(1)转化(OC中的强转)
//需要注意的是 需要转换的数据必须是包装类才行,基本类型不能被强转
Double s = 10.22;
Int w = s.intValue();
float d = s.floatValue();
Integer.valueOf(“30”);转为Integer类型
15.String类
(1)初始话字符串
String d ;
String w = “ssss”;
d = String.format(“qweqwe”+”qwe%s”,w);
String s = “test”;
String m = “game”;
(2)计算字符串长度
s.length();
(3)判断字符串是否相等,区分大小写(返回bool值)
s.equals(m);
(4).拼接字符串
s.concat(m);
或者(下面的更常用)
s+m
(5).查找指定位置的字符
char l = s.charAt(1);//l = e
(6).字符串对比
s.compareTo(m);
(7)和可变字符串比较
StringBuffer k = “ssss”;//可变字符串
s.contentEquals(k)
16.StringBuilder和StringBuffer(修改的是自己,不会产生新的变量)
都属于可变字符串,StringBuilder更快但是线程不安全,不考虑线程安全,平时使用StringBuilder
举例StringBuilder
StringBuilder builder = new StringBuilder(“ceshi”);
(1)拼接字符串
builder.append(“m”);
(2)删除指定位置的内容
builder.delete(int start,int end);
(3)替换字符串内容
Builder.replace(int start,int end, String replaceContent);
(4)判断字符串中是否有某个字符串
builder.indexOf(content);//不等于-1就是有
(5)字符串中插入内容
builder.insert(int offset, insertContent);
17.数组
(1)初始话
double [] myList;//这种写法只是声明了一个数组,但是没有任何的实现,不能往里面添加元素,
//因为数组没有被初始话也可以写成double myList[];
创建数组必须写明大小(跟C一个德行)
int[] m = new int[20];
for-each循环(for-in)
for(type element:array){
}
18.正则表达式
(1)如果要查找字符串中的某个特殊符号在前面加\就可以.
(2)不能将限定符和定位符一起使用
非打印字符
\n:匹配换行符
\r:匹配回车符
\s:匹配所有的空格
\S:匹配所有的非空格
\t:匹配制表符
特殊字符
^:这个符号代表字符串的开始位置
$:这个符号代表匹配字符串的末尾的位置,如果要匹配这个符号需要加\即\$
():这个标记一个子表达式的开始和结束,如果匹配这个字符\(\),他的作用有点像是把要匹配的内容
括起来比如:(ab){1,3}是匹配ab这个最少能匹配一次最多三次,但是ab{1,3}就变了变成了
匹配a后面跟的b最少一次最多三次.
*:这个符号代表匹配前面的子表达式零次或多次{0,}//尽可能多的匹配
+:这个符号代表匹配前面的表达式1词或多次{1,}//至少匹配一次
.:这个符号代表匹配除换行符\n之外的其他字符//
[:这个符号代表一个中括号表达式的开始
?:这个符号代表匹配前面的子表达式零次或一次{0,1}
\:这个符号代表将下一个字符标记为需要查找的内容
|:这个符号代表两项之间的旋转”或”
{:这个符号代表限定符表达符的开始
限定符
{n}:n是非负的整数,匹配确定的n次.
举例:
‘o{2}’不能匹配”bob”中的”o”,但是能匹配”food”中的”oo”因为需要匹配两个o
{n,}:n是非负的整数,至少匹配n次
{n,m}:最少匹配n次,最多匹配m次,注意逗号和数字间不能有空格或其他
定位符
\b:匹配一个单词的边界,即字与空格的位置
如果\b在单词的开始位置那么他在单词的开始处查找,如果在单词的结尾处那么在单词的结束位置查找
举例:
/\bm/ 这个写法在mba中可以找到,但是在num和name中找不到
/m\b/ 这个写法在mba和name中找不到,但是能在num中找到
\B:非单词边界
i:代表不区分大小写
g:代表尽可能多的查找
其他
\d:等价于[0-9]
\w:等价于[a-zA-Z0-9_]
\W:等价于[^a-zA-Z0-9]
[^]:代表不包含
19.方法
(1)方法首字母为小写,不使用链接符(_)
(2)方法重载:相同的方法名,不同的参数就是方法重载,重载的方法必须拥有不同的参数列表,不能仅仅依靠修饰符或返回类型不同来重载方法
(3)构造方法
public class Dog{
Public Dog(){
}
}
class Cat{
Cat(){
}
}
20.java异常处理
(1)检查性异常(Exception)
(2)运行时异常(RuntimeException)
(3)错误(Error)
Exception类(检查性异常类)有两个主要的子类IOException和RuntimeException
使用try{
}
catch(e){
}
finally{
}
Finally无论是否抛出异常都会执行的方法
二JAVA面向对象
21.继承
Class 父类 {
}
class 子类 extends 父类{
}
类的继承是单一的,使用implements可以使类具有多继承的概念,使用的前提是类实现的是接口(interface),可以实现多个接口(接口之间用逗号隔开)
public interface B{
}
public interface C{
}
//A是一个类B,C是两个接口
public class A implements B,C{
}
Super关键字子类可以对父类的成员进行访问
This关键字子类可以访问自己的成员
Final 修饰的类不能被继承.并且他修饰的方法不能被子类重写,但是子类可以访问到
子类不能继承父类的构造器,但是如果父类的构造器方法有参数的话子类需要通过super关键字显式调用
//父类
public class superClass{
public superClass(int n){
}
}
子类
public class subClass extends superClass{
public subClass(){
super(200);//显式的调用父类的构造方法
}
}
如果父类构造函数中没有参数,就不需要显式的去调用super这个时候系统会默认的自动调用父类的构造方法
22.java重写(override)和重载(overloading)
(1)重写是子类对父类的方法进行重新定义,但是参数返回值必须保持一致,里面的实现过程变了,总的就是说壳子不变,内容变了
如果子类重写了父类的方法但是还想用父类的方法就得使用super.methed()
(2)重载是指参数名不变但是参数必须不一样的方法.
(2)重载是指方法名不变但是参数必须不一样的方法.
(3)方法重载是一个类多态性的表现
(4)重写方法访问限制门槛可以降低但是不能提升(protected可以变public但是不能变private)
23.多态(同一个事件在不同的对象上会产生不同的结果就是多态)
多态存在的必要条件
(1)继承
(2)重写
(3)父类引用指向子对象(向上转型)
举例:
Parent p = new child();
p相当于遥控,child相当于电视,虽说后面操作的是遥控但是操作的对象确实电视,所以走的还是电视的方法
这个p是引用(相当于遥控),p指向的是child对象(相当于电视),在调用方法时调用的是child的方法.但是在编译的时候会检查引用的里面是否有这个方法,如果p中没有child中的某个方法但是p要调用会报错.(所以涉及到了继承和重写)
向上转型:子类转为父类(父类的引用指向子类的对象),向上转型后,子类不能使用使用父类没有的方法
向下转型:父类转为子类,举例:Parent p = new child(); child c = (child) p;子类的引用指向父类指向的子类的对象,这就是向下转型
24.抽象类(abstract)(继承抽象类的方法必须实现,抽象类的所有抽象方法)
(1)抽象类不能被实例化为对象,但是其他的功能还是有的比如变量方法构造方法和访问方式等.
(2)抽象类不能被实例化为对象,所以他必须被继承才能使用.
(3)一个类只能继承一个抽象类,但是可以实现多个接口
(4)一个类中包含抽象方法,那么这个类肯定是抽象类
(5)继承抽象类的子类必须实现实现抽象类的所有抽象方法,除非子类本身是抽象类就不用必须实现
(6)抽象类中不一定包含抽象方法
(7)构造方法和类方法(被static修饰的)不能被定义为抽象方法
(8)抽象方法: public abstract void methodname();
(9)抽象方法没有实现方法,没有大括号到小括号就截止了.举例:public abstract void methodname();
(10)抽象方法不能被修饰为static和final
25.接口(interface)
(1)接口是抽象类型,是抽象方法的集合,一个类通过implements(实现)接口的方式,从而来实现接口的抽象方法
(2)接口不是类,编写接口的方式和类很相似,但是他们属于不同的概念,类描述对象的属性和方法,接口则包含类要实现的方法
(3)除非实现接口的类是抽象类,否则这个类要实现接口的所有方法
(4)接口无法被实例化,但是可以被实现
(5)一个接口可以有多个方法
(6)接口不能实例化
(7)接口没有构造方法
(8)接口中所有的方法必须是抽象方法,即使不声明也是抽象的方法
(9)接口中不能定义成员变量,除了static和final变量(但是默认是可以创建的,创建完了以后系统会将其默认为static final常量,而且这里面一般用不到变量所以不需要定义,但是可以存储常量)
(10)接口不是被类继承了,而是要被类实现
(11)接口支持多继承
(12)接口中的方法不能被接口实现,只能由实现接口的类来实现
(13)一个类只能继承一个抽象类,但是能实现多个接口
(14)接口中的方法都是抽象方法,没有实现部分,可以不用写abstract字段
接口和多态配合使用才更有意义,也必须这么用否则失去了接口的意义
举个例子
先创建一个interface类名字是A,定义一个方法,和一个变量
public interface A{
//可以借用接口实现常量的定义,因为接口中的没有变量这一说,默认的都会被声明为常量
int m= 0;
void eat();
}
//定义一个接口C
public interface C{
void bark();
}
//B这个类实现了A和C,所以必须实现他们两个的这个接口方法,这样就实现了”多继承”
public class B implements A,C{
public void eat(){
system.out.printin(“我吃饭了”)
}
public void bark(){
}
//使用的时候可以这么玩
public B(){
//b是引用,new B();是对象最终执行的是对象的方法
A b = new B();
b.eat();//打印的是我吃饭了
system.out.printin(A.m);
}
}
26.java 包package
(1)把功能类似或相关功能的类或接口组织到同一个包中,方便类的查找和使用
(2)相当于文件夹,但是不同的包中的类的名字可以和其他包中的类名相同
三JAVA高级教程
27.数据结构
主要介绍了以下几种接口和类
枚举,位集合,向量,栈,字典,哈希表,属性
接下来一一介绍以上内容
(1)枚举(Enumeration)
Enumeration中定义了一些方法,通过这些方法可以枚举(一次获取一个)对象集合中的元素.但是这些传统的接口已经被迭代器替代了,虽说Enumeration还未被废弃但是已经很少被用到了.但是他还是使用在诸如Vector和Properties中这些传统类中所定义的方法中,除此之外还应用在一些API类中,并且在应用程序中广泛使用.下面总结的是Enumeration声明的方法
boolean hasMoreElement()//测试该枚举是否有更多的变量
Object nextElement()//如果该枚举对象至少还有一个可提供的元素,则返回该枚举的下一个元素
代码实例:
import java.util.Enumeration
import java.util.Vector
public class A{
Enumeration<String> days;
Vector<String> daysName = new Vector();
daysName.add(“1”);
daysName.add(“2”);
daysName.add(“3”);
days = daysName.elements();
while(das.hasMoreElements()){
system.out.printin(das.nextElement());
}
}
//运行结果是1,2,3
(2)位集合(BitSet)非线程安全的,如果需要在线程中使用要注意
BitSet是存储的二进制数据,并且操作也是操作的二进制
BItSet常用来大数据处理查找或其他的操作
BitSet会创建一种特殊类型的数据保存位值,BitSet中数组的大小会随着需要而变化
BitSet有两种构造方法
BitSet()//创建一个默认的对象
BItSet(int size)//这个构造方法允许用户自己初始大小,但是所有的位初始值为0(false).
下面说一下他的方法,代码见JAVA工程
(3)Vector(下面提到的组件就是Set和Map的实现类)
Vector 主要用在事先不知道数组元素有多少的情况,实现了动态数组,他是同步的不是异步的,有四种构造方法,记得区分组件和元素和List
第一:Vector();//默认向量大小为10
第二:Vector(int size);//指定向量大小
第三:Vector(int size,int incr);//指定向量的大小,并且用增量incr指定,增量表示向量每次增加元素的数目
第四:Vector(Collection c);创建一个包含集合c元素的向量
常用方法
import java.util.*
public class VectorTest{
public VectorTest(){
Vector vector = new Vector();
//添加元素到末尾
vector.add(“1”);
//添加元素到指定位置(添加到索引值为1的位置,注意如果vector中的元素有5条那么我们
只能添加到索引值为5或比5小的位置,不能添加到比索引值5更大的位置会报错),
vector.add(1,”3”);
//将指定的组件添加到向量的末尾
vector.addElement(Object obj);
//返回当前向量的容量
int size = vector.capacity();
//清空该向量中的所有元素
vector.clear();
//克隆一份该向量的副本
Vector v = vector.clone();
//判断该向量是否包含指定的元素
boolean have = vector.contains(Object elem);
//将该向量的组件复制到指定的数组
vector.copyInto(Object [] array);
//返回指定位置的组件
Object obj = vector.elementAt(int index);
//返回该向量的枚举Enumeration
Enumeration<Object> elements;
elements = vector.elements();
//比较指定对象与该向量的相等性
boolean also = vector.equals(Object obj);
//返回该向量的第一个组件
Object obj = vector.firstElement();
//返回该向量的指定索引位置的元素
Object obj = vector.get(int index);
//返回该向量的哈希code
int hashCode = vector.hashCode();
//返回该向量第一次出现指定元素的位置(不包含返回-1)
int index = vector.indexOf(Object obj);
//返回该向量从指定索引开始,往后出现指定元素的位置(不包含返回-1)
int index = vector.indexOf(Object elem, int index);
//向该向量中插入组件
vector.insertElementAt(Object obj,int index);
//测试该向量中是否”不”包含组件
boolean have = vector.isEmpty();
//返回该向量的最后一个组件
Object obj = vector.lastElement();
//返回该向量最后一次出现指定元素的索引(不包含返回-1)
int index = vector.lastIndexOf(Object obj);
//返回该向量从指定位置逆向搜索,最后一次出现指定元素的位置(不包含返回-1)
int index = vector.lastIndexOf(Object obj, int index);
//删除向量中指定位置的元素
vector.remove(int index);
//删除指定元素第一次出现的那个
vector.remove(Object elem);
//从此向量中移除所有组件并将其大小设为0
vector.removeAllElements();
//移除索引值最小的与该元素匹配的元素
vector.removeElement(Object obj);
//移除指定索引的组件
vector.removeElementAt(int index);
更多详情:[https://www.runoob.com/java/java-vector-class.html](https://www.runoob.com/java/java-vector-class.html)
}
}
(4)栈(Stack)
栈的规律是先进后出,后进先出,他是Vector的子类,最后一个进的在栈顶
方法详情:https://www.runoob.com/java/java-stack-class.html
(5)字典(Dictionary)(过时了不用它)
字典是一个抽象类,他定义了一个键映射到值的数据结构
(6)Map
Map接口中键和值一一映射,可以通过键来获取值
异常:https://www.runoob.com/java/java-map-interface.html
public MapDemo{
public class MapDemo(){
Map m = HashMap();
m.put(“key”,”value”);
//判断key值是否存在
boolean have = m.containsKey(“key”);
//判断这个值是否存在于Map
boolean have = m.containsValue(“value”)
//比较指定的对象与该映射是否相同
boolean result = m.equals(Object obj);
//通过key获取值,如果没有返回null
Object object = m.get(“key”);
//判断该map是否为空
boolean empty = m.isEmpty();
//将一个Map复制到一个Map
Map p = new HashMap()
m.putAll(p);
//通过key移除键值对
m.remove(“key”);
//返回键值对的个数
int num = m.size();
//清空键值对
m.clear();
}
}
(7)Hashtable
Hashtable和HashMap很像,但是他支持同步
Hashtable可以存储多种数据
Hashtable的构造方法有四种
第一:Hashtable();默认的
第二:Hashtable(int size);创建指定大小的哈希表
第三:Hashtable(int size, float fillRatio);创建一个指定大小的哈希表,通过fillRatio指定填充比例,填充比例0.0-1.0,他决定了哈希表在重新调整大小前的充满程度
第四:Hashtable(Map m);创建了一个以m为中元素为初始话元素的哈希表.哈希表的容量被设置为m的两倍
方法使用
public class HashtableDemo{
public HashtableDemo(){
Hashtable table = new Hashtable();
Enumeration names;
String str;
double bal;
给Hashtable赋值
table.put(“key”,new double(1232.3));
//返回此哈希表中的键(key)的枚举
names = table.keys();
while(names.hasMoreElements()){
//取到了key
str = (String)names.nextElement();
//可以通过key取value
//table.get(str);这个把value取到了
}
}
}
四.集合框架
28.Java集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另外一种是图(Map),存储键/值对映射.
Collection接口又分为三种子类型:List,Set,Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList,LinkedList,HashSet,LinkedHashSet,HashMap,LinkedHashMap等.
集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含以下内容
(1)接口:是代表集合的抽象数据类型
(2)实现(类):是集合接口的具体实现
(3)算法:是实现集合接口的对象里的方法执行的一些运算,例如,搜索,排序等.这些算法被称作多态,因为相同的方法在相似的接口上有着不同的实现
29.集合接口
集合框架定义了一些接口
(1)Collection(集合的最顶层接口,他的下一级仍然是接口,下一级有三个接口Set,List,Queue,再下一级就是实现类了不是接口了(SortedSet例外))
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素.java不提供直接继承自Collection的类,只提供继承与Collection的子接口(List和Set)
Collection接口存储一组不唯一(可以重复),无序的对象
(2)List
List接口是有序的Collection,他存储一组可重复的(可以重复),有序的(插入顺序)对象
(3)Set
Set和Collection有完全一样的接口,只是行为上不同,Set不保存重复的元素,Set接口存储一组唯一的,无序的对象(存储对象不能重复)
(4)SortedSet
继承于Set,保存一组唯一的有序的集合.(不能重复)TreeSet是他的实现类.
(5)Map
Map接口存储一组键值对象.提供key(键)到value(值)的映射
(6)Map.Entry
描述在Map中的一个元素(键/值对),是一个Map的内部类
(7)SortedMap
继承于Map,使key保持在升序排列
Set和List的区别
(1)Set的接口实例存储的是无序的,不重复的数据.List接口实例存储的是有序的,可以重复的数据
(2)Set的检索效率低下,但是删除和插入的效率高,插入和删除不会引起元素的位置变化/实现类有<HashSet,TreeSet>
(3)List和数组类似,可以动态增长,根据实际存储的数据的长度自动增加List的长度.查找元素效率高,但是删除插入的效率低.因为会引起其它元素的位置的改变.实现类有<ArrayList,LinkedList,vector>
30.集合实现类(集合类).下面只列出常用类(https://www.runoob.com/java/java-collections.html)
(1)LinkedList(查找效率低,插入删除的效率高)
这个类实现了List接口,允许有空元素(null),主要用来创建链表数据结构,该类没有同步的方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决的方法就是自己在创建的时候创建一个同步的List
举例:
List list = Collections.synchronizedList(new LinkedList);
(2)ArrayList
该接口也实现了List的接口,实现了可变大小的数组,随机访问和遍历数组时效率更好,该类也是非同步的,在使用多线程的时候不要使用这个类
(3)HashSet
该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含null数据,但是只能是一条.
(4)LinkedHashSet
具有可预知迭代顺序的Set接口的哈希表和连接表的实现
(5)TreeSet
该接口实现了Set接口,可以用来实现排序等功能
(6)HashMap
HashMap是一个散列表,他存储的内容是键值对映射,该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问数据,最多允许一条键(key)为null,不支持线程同步
Vector和ArrayList很像,但是该类是同步的.如果是多线程可以使用这个类(Vector)安全.
31.遍历
(1)遍历ArrayList
import java.util.*;
public class Test{
public Test(){
List<String> list = new ArrayList<String>()
list.add(“1”);
list.add(“2”);
list.add(“3”);
//for:each
for(String elem : list)
{
system.printin.out(elem);
}
//把链表变成数组相关进行遍历
String[] strArray = new String[list.size()];
list.toArray(strArray);
for(String elem : strArray)
{
system.printin.out(elem);
}
//使用迭代器
Iterator<String> ite = list.iterator();
while(ite.hasNext()){//判断下一个元素有值
system.printin.out(ite.next());
}
}
}
以上的三种方法都是用来ArrayList的,Iterator迭代器遍历的好处是不用担心数组越界
(2)遍历Map
import java.util.*;
public class mapDemo{
public mapDemo(){
Map<String,String> map = new HashMap<String,String>();
map.put(“1”,”2”);
map.put(“3”,”4”);
map.put(“5”,”6”);
//第一种方法,普遍使用,二次取值,通过Map.keySet遍历key和value
for(String key : map.keySet()){
system.printin.out(key+map.get(key));
}
//第二种方法使用迭代器Iterator遍历,通过使用Map.entrySet();
Iterator<String,String> ite = map.entrySet().iteartor();
while(ite.hasNext()){
Map.Entry<String,String> entry = it.next();
system.printin.out(entry.getKey()+entry.getValue());
}
//第三种推荐,尤其是大容量时,通过Map.entrySet()
for(Map<String,String> entry : map.entrySet()){
system.printin.out(entry.getKey()+entry.getValue());
}
//第四种使用Map.values()遍历所有value但是不能遍历key
for(String value : map.values()){
system.printin.out(value);
}
}
}
32.泛型(泛型提供了编译时类型安全监测,预编译检查)
我的理解:泛型就是相当于iOS中的ID类型可以接收任何类型.
泛型方法定义规则
(1)所有的泛型方法声明都有一个类型参数声明部分(由尖括号分隔).该类型参数声明部分在方法返回类型之前(在下面的例子中的<E>);
(2)泛型方法的声明和其他的方法一样,注意类型参数只能代表引用型类型(Integer,Double,Character等),不能是原始类型(int,char,double等);
(3)类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符.
(4)泛型只在编译阶段有效
代码见工程->
第三方详解
泛型在编译结束后会被擦除掉,正常情况下会变为Object,但是我们也能指定他擦除的替代的类型,不一定非得是Object.详解见下面👇
泛型即’参数化类型’,就是将原来具体的类型参数化
泛型分为泛型类,泛型接口,泛型方法
(1)泛型类
泛型类型用在类的定义中,被称为泛型类.通过泛型可以完成对一组类的操作对外开放相同的接口.
泛型重载了extend关键字,可以通过extend关键字指定最终擦除所替代的类型.(要求传入的必须是某个类型或其子类的时候使用这个方法)
模板:ClassName必须是类类型或自定义类比如String,Integer,不能是int这些基本类型
public class ClassDemo<ClassName>{
//public class ClassDemo<T extend ClassName>{
public ClassDemo(T key){
}
}
//执行的操作写法:
ClassDemo demo = new ClassDemo(123);
ClassDemo demo = new ClassDemo(“123123123”);
或者
ClassDemo<Double> demo = new ClassDemo(123.324);
上面的两种写法都可以
下面的这是泛型类
示例代码
public class Node<E extend People>{
private E obj;
public E get(){
return obj;
}
public void set(E obj){
this.obj=obj;
}
public void playName(){
System.out.println(obj.getName());
}
}
通过extend编译器会将所有的类型都擦除为people或其子类
//只能读不能存
public static void playTest(List <? extend Fruit> list){
Fruit f = list.get(0);//这个是可以的因为都是Fruit的子类可以进行向上转型.然后就可以直接操作子类了.
list.add(new Apple());//这个时候这段代码会报错的
}
代码List <? extend Fruit> list 代表需要一个List,list里面装的必须是Fruit的子类类型.但是对传入的list进行操作会报错比如存取;
报错原因:因为知道list中的元素肯定是Fruit的子类,但是不知道是哪种可能是Apple也可能是orange,所以为了安全起见,编译器是不允许在这里面添加内容的.取得话可以通过向上转型可以实现.
//只能存不能取
public static void playTest(List <? super Fruit> list){
list.add(new Apple());//可以正常运行,因为list中存的是Fruit的父类型,所以可以往这里面添加他的子类
Apple a = list.get(0);//会报错
Object o = list.get(0);//正常
}
代码List <? super Fruit> list 代表需要一个List,list里面装的必须是Fruit的父类类型. 但是对传入的list进行操作会报错比如取;
报错原因:因为list中存储的是Fruit的父类型,所以取得时候不知道到底是哪个父类,因此编译器不允许取.但是可以使用Object进行读取
泛型接口
public interface Generator(T){
public T next();
}
泛型方法的格式
Public和返回参数类型之间的<T>很重要有他才是泛型方法,下面的T代表返回参数类型,tClass传入的泛型实参
public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
IllegalAccessException{
T instance = tClass.newInstance();
return instance;
}
网友评论