注意: 凡是java中,要截取索引值的内容都是包头不包尾!!也就是 start - end.
1. JVM有常量优化机制.在编译的时候进行的
2. 通过gbk码表一个中文代表两个字节,而且中文的第一个字节一定是负数.
3. JVM在打印对象引用的时候默认打印toString方法 .
4. 如果打印一个引用类型变量时,结果不是Object 类的toString方法的结果(哈希码值)
那么就一定是重写了tostring 方法,本类没找到那么父类一定有.
String类
注意:
(1) String 重写了toString 方法,所以打印是的自己本身.字符串是常量,一旦赋值就不可以被改变.在使用数推荐用StringBuffer类,因为String类会不断制造垃圾对象.
(2) 解码:就是把计算机看的懂得转化为我们可以看懂的.
(3) Java中 == 基本类型比较的是值,引用类型比较的是哈希码值. Equals比较的是对象的局数值.
String面试题 在开发中最少出一个.
1. 构造方法(一个数组转化为字符串)
String
()
初始化一个新创建的String
对象,使其表示一个空字符序列
String
(byte[] bytes)
解码指定的 byte 数组,构造一个新的String
String(byte[] bytes,int offset(
开始索引), int length(多少个字符))
转一部分(int offset:从哪个索引开始.int length (转多少个)
String
(char[] value)
分配一个新的String
,其表示字符数组参数中当前包含的字符序列。
String
(char[] value,int offset(
开始索引),int count(多少个字符))
String
(int[] codePoints, int offset,int count)
总结: 构造方法中没有单int数组的形参构造.更没有short,float,double的形参.
2. 获取的方法 每天练习.
1> Int length() 获取字符串的长度
2> char charAt(int index)
根据索引获取对应位置的字符,可以用于遍历字符串 (注意角标越界)
3>int indexOf
(int ch)
返回指定字符(ch)在字符串中第一次出现的索引。
4> int indexOf
(int ch, int fromIndex)
(int ch :需要寻找的字符, int fromIndex:从哪个索引值开始找)
例:String st = “abcd”; int a = st.indexOf(‘b’, 2)
5> Int indexOf
(String str) 返回小串在大串中第一次出现的索引值,若没有则返回-1.
6> Int indexOf
(String str,int fromIndex)
(String str : 需要查找的小串,int fromIndex:从哪个索引值开始找)
7> Int lastIndexOf
(String str,intfromIndex)(
从指定位置向前找,返回索引)
8> String substring
(int beginIndex)//
从指定位置截取字符串,默认到末尾.
例: String st=”abcdefgh”
String st1=st.substring(2)//
从索引值为2的字符开始截取st的字符串.默认到结尾.
9> String substring
(int beginIndex, int endIndex)
从指定位置开始到指定位置结束截取字符串.(包头不包尾)
10 > int lastIndexOf (int ch)获取最后一个字符的位置
3. 判断的方法
1> boolean equals(Object anObject) 是否相等
boolean equalsIgnoreCase(String anotherString) 忽略大小写是否相等
2> Boolean contains(String str) 大串中是否包含小串 应用:搜索
3> startsWith
(String prefix)
是否已指定子串开始
Boolean endsWith(String str) 是否以指定子串结束
4> Boolean isEmpty()是否长度为0 如:
’’ ” 与null的区别: “ ”:是字符串常量,同时也是String对象.可以调用String中的方法
null : 是空常量,不能调用任何方法,可以给任意的引用数据类型赋值.
5. 转换的方法 [比较重要.] 每天都要练一次.
1> 字符数组等 转化为字符串 (解码: 把计算机看的懂的转化为我们可以读懂的)
1> > 构造方法
String(char[] c) 将字符数组转换为字符串(构造方法)
String(char[] c, int a, int b)
2> > 调用valueOf 可以将任意类型转化为字符串.
Static String valueOf (char[] data) 把字符数组转化为字符串
Static String valueOf(char[] data, int offset,int count)
valueOf其实底层也是用构造方法去实现的.相当于把String的构造方法封装起来了.
注意的是: 调用valueOf方法只有char数组,byte与int数组装化为字符串只有用构造方法才可以.只能传入单个数组转化为字符串.例: valueOf(100).
2> 字符串 转化为 字符数组等 ( 编码: 把我们读的懂的转化为计算机读得懂的额 )
char[] toCharArray() 将字符串转换为字符数组 (char 只有这一种方法.)
byte[] getBytes(); 把字符串转化为字节数组.
注意: 通过gbk码表一个中文代表两个字节,而且中文的第一个字节一定是负数,第二个字节有可能是正数.
3> 字符串之间的转换
String toUpperCase() 转大写
String toLowerCase() 转小写
6. 其他方法
String replace(char oldChar, charnewChar) 替换字符
String replace(String old,String new ) 替换字符串
String replaceAll
(String regex,String replacement)
正则替换.
1>
String[] split(String regex) 正则切割(
只能切割字符串不能切割数组)
可以用于字符串排序.
split
(String regex,int limit)
正则切割几刀.
boolean matches
(String regex)
正则匹配 str.matches(regex)
String trim() 去除两端的空格(一般用于注册用的)
Int compareTo(String str) //s.compareto(s1); 按照字典的顺序比较字符串. 字符一个一个的比较. 例:
Int compareToIgnoreCase() //按照字典的顺序比较字符串不区分大小写的比较.
String concat( String st) // 两个字符串拼接.//不推荐使用.因为只能是字符串拼接.
优先使用 + 来拼接.
StringBuffer 类,
String 与stringBuffer的区别:
1> String是一个不可变的字符序列.(会制造很多垃圾对象)
2> StringBuffer是一个现成安全的且效率低的可变字符序列(不会制造垃圾对象)
1. 构造方法
1>
StringBuffer
()
构造一个不带字符的字符串缓冲区,默认容量为16.
2>
StringBuffer
(int capacity)
指定初始容量.
例:new StringBuffer(10);容量为10的字符串缓冲区.
3>
StringBuffer
(String str)
字符串的缓冲区.
例:new StringBuffer(“heima”)
2. StringBuffer的添加功能
1> append
(String str)
可以添加任意的类型到缓冲区中.并返回字符串缓冲区本身.
2> insert
(int offset, char c)
在指定位置把任意类型的的数据插入到缓冲区中,并返回缓冲区本身.
3. StringBuffer的删除功能
1 > deleteCharAt
(int index)
删除指定索引的字符.
2 > delete
(int start, int end)
删除起始索引和结束索引的字符.
4.
StringBuffer
类的替换和反转
1>
replace
(int start, int end,String str)
替换
(
包含头不包含尾 == end – start的个数.).
2>
reverse
()
反转.
5.
StringBuffer
的截取功能.
1>
String substring(int start)
2>
String substring
(int start, int end)
注意: 返回的值不是stringBuffer 而是String
6.
其他方法
1>
capacity
()
返回当前容量.
2>
Char charAt(int index)
还回指定索引处的字符.
3> Int codePointAt
(int index)
还回指定索引处的字符
ASCII码值
.
7. String和stringBuffer的相互转换.
1> String-----à stringbuffer
构造方法,new StringBuffer(str)和 append()方法.
2> Stringbuffer-----à string
构造方法, tostring()方法,
substring(0, length) ----常用的.
8. String , StringBuffer与 StringBuilder 的区别和联系
1> String 是一个不可变的字符序列.
StringBuffer 是1.0版本的-是线程安全的同步的,效率低, StringBuilder1.5版本的-是线程不安全的不同步的,效率高.
2> String虽然是引用类型但是在当做参数传递时,和基本类型是一样的.(就是因为一旦被赋值就不会被改变的特点)
Arrays类的方法.
1> toString(int[] a);//打印数组字符串
2> sort(int [] a);//给数组排序.
3> binarySearch(int [] a, int key);//二分查找.
基本类型包装类
1. 将基本类型封装成包装类的好处:是可以在对象中定义更多的功能方法操作该数据.
常用的操作是: 用于基本类型与字符串之间的转换.
2. 基本类型与包装类的对应
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
3. Integer举例
1> Integer没有空构造的方法.只有两种如下.
例: Integer a = new Integer(100);
Integer b = new Integer("100");
System.out.println(a + 100);//打印出200 说明a是int类型.
System.out.println(b+100);//打印出200
2> 且最小值MIN_VALUE
最大值MAX_VALUE
3> 基本类型和引用类型相互转换.
Int---àstring : 最推荐前2种.
1/ 直接和 “”相连, 例: syso(100 + “”);
2/ 直接调用String类的valueOf方法, 例:syso(String.valueOf(100));
3/直接调用Integer的tostring(int a);例:syso(Integer.tostring(100));
注意的是:Integer的空参tostring()不是静态的.
Int[] ---à String
1: s = s + a[i] + “ ”; 2: s += s.append(a[i] + “ ”);
String--àint 最推荐第1种.其次第二种.
1/ 直接调用静态的parseInt();例:syso(Integer.parseInt(“100”));
2/ 用Integer的构造:例:int a =new Integer(“100”);
3/ 用integer类中的intValue();
总结: 基本数据类型的包装类中.其中7种(除了char)都有parsexxxx()的方法,可以讲这7种的字符串表现形式转换成基本数据类型.
为什么:char类型没有呢 因为char c = integer.pasexxx(“abcde”)中c只能存一个字符. 所以不可能成立.
Char 只能用 toCharArray()来把字符串转化为字符数组.
4> 自动装箱和拆箱JDK1.5的新特性
自动装箱:把基本数据类型转换为包装类类型.
自动拆箱: 把包装类类型转换为基本数据类型.
例:Integer i = 100;//自动装箱
int a = I + 200;//自动拆箱.
注意的是:-128到127是byte的取值范围,如果在这个取值范围内,自动装箱就不会新创建对象,而是从常量池中获取, 如果超过byte取值范围就会再创建新的对象.
4. Reges 正则表达式 [主要看 API的内容]
在ptterm类中. Java.util.regex
2> [ ]表示单个字符.
3> [\\d]数字字符 [\\D]非数字字符.
4> [x]* 零次或多次. [x]+ 一次或多次 [x]{n}恰好出现n次, {n,}最少出现n次,{n,m}出现的次数在这个范围内.
5>
String[]
split
(String regex)
切割功能.(只能切割字符串不能切割数组)
String[]
split(String regex,int limit)
正则切割.
String
replaceAll(
String regex,
String replacement)
正则替换.
Boolean matches
(String regex)
正则匹配.str.matches(regex);
6>
正则的分组功能
格式:是左括号为准.
例: ((A)(B(C))) :表示 1. ((A)(B(C)))2. (A)3. (B(C))4. (C)
叠词的正则: 快快乐乐
正则表示: (.)\\1(.)\\2//\\1代表 第一组再出现一次.\\2代表第二组再出现一次
例:
String st = "我我....我...我.要...要要...要"
+"学....学学..学.编..编编.编.程.程.程..程";
System.out.println(st.replaceAll("\\.","").replaceAll("(.)\\1+","$1"))
//$1表示获取到第一组的数据.
5. Matcher类 与Pattern类 //获取字符串中的额手机号码.很重要
Pattern和Matcher的结合使用
String st = "我现在的手机号是15181007725,以前用18988888888,还用过 13488888888";
Pattern p1 = Pattern.compile("1[3458][\\d]{9}");//获取一个正则表达式
Matcher m1 = p1.matcher(st); // 获取一个匹配器
while(m1.find()) //是否有--与正则表达式相匹配的字符串
System.err.println(m1.group());//输出find()找到的字符串.
6. Math类概述
* publicstatic int abs(int a) //绝对值
* public static double ceil(double a)//天花板
* public static double floor(double a)//地板
* public static int max(int a,int b) min自学//最大数,最小数
* public static double pow(double a,double b)//a^b
* public static double random() //0~1的随机数
* public static int round(float a) 参数为double的 //自学四舍五入
* public static double sqrt(double a) 开平方.
7. Random 类. 用于生成随机数字流.
1>> 构造方法
Random r = new Random();//创建一个随机数生成器,它的种子是一个变化纳秒值,
Random r1 = new Random(5);创建一个以种子5的随机数生成器,地层是根据//算法(地层是以种子为算法的,种子确定了随机数就确定了.)
int i1 = nextInt();//这个是生成一个int取值范围内的随机数.
例: int i2 = nextInt(100)//表示生成一个0 -99之间的随机数.重点掌握
//这个可以用来猜数字游戏
8. System类
1> > System类不可以new对象.
System.in 标准键盘输入流,system.out 输出流,system.err错误输出流
2> > 方法
public static void gc()//垃圾回收器.
public static void exit(int status)//终止JVM 非0表示异常关闭
public static long currentTimeMillis()//获取当前时间毫秒值
pubiic static void arraycopy(Object src, int srcPos, Object dest, int destPos, intlength) //拷贝数组.很重要集合的底层用这个
src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量
9. BigInteger 类 在Math 的包下 (不用于金融和证券 了解即可 )
表示任意精度的整数.
*可以让超过Integer范围内的数据进行运算
B:构造方法
*public BigInteger(String val)
C:成员方法
*public BigInteger add(BigInteger val) // + 加
*public BigInteger subtract(BigInteger val)// - 减
*public BigInteger multiply(BigInteger val)// * 乘
*public BigInteger divide(BigInteger val)// /(除)
*public BigInteger[] divideAndRemainder(BigInteger val) //除数和余数的数组.
BigDecimal 为了更精确的存储小数. (了解)
开发是推荐用两种方法.(更精确)
1.
BigDecimal(String val)
字符串的构造方法.
例:
BigDecimal bd1 = new BigDecimal(“2.0”);
BigDecimal bd2 = new BigDecimal(“1.1”);
Syso(bd1.
Subtract(bd2));
2.
static BigDecimal valueOf
(long val)
方法.
例: BigDecimal bd1 = BigDecimal.valueOf(2.0);
BigDecimal bd2 = BigDecimal.valueOf(1.1);
Syso( bd1.
Subtract(bd2));
10. Date 类 表示特定的瞬间.获取当前时间对象
*A:Date类的概述
* 类 Date 表示特定的瞬间,精确到毫秒。
*B:构造方法
*public Date() //代表的是当前时间
*public Date(long date)//参数传为0 表示1970年1月1日0点的时间.
//传递的是大于0的数就是 初始时间加上这个数
*C:成员方法
* public long getTime()//通过时间对象获取当前时间的毫秒值.
( System.currentTimeMillis()通过系统类的方法获取毫秒值.)
* public void setTime(long time)
等效于 publicDate(long date)有参对象. 没什么卵用.
只是setTime是改变时间对象,构造是创建一个时间对象
10.DateFormat是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。是抽象类,所以使用其子类SimpleDateFormat
11. SimpleDateFormat 日期格式化类 查看API
* B:SimpleDateFormat构造方法
* public SimpleDateFormat()
* public SimpleDateFormat(String pattern)
*C:成员方法 查看API
* public final String format(Date date) //将日期转换为字符串.
例:Date d =new Date();SimpleDateFormat sdf = SimpleDateFormat(“y/M/dH:m:s”);
Syso(sdf.format(d));
*public Date parse(String source)//将字符串转换为日期对象.
例: String s = “2000/08/08 08:08:08”;//这里一定要和下面的格式对应起来
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy/MM/ddHH:mm:ss”);
Date d = sdf.parse(s);
练习:求我来到这个世界多少天.
12. Calender类 看API是抽象类,他的方法其实都是在子类实现的.他的直接子类是
例: Calender c = Calender.getInstance();//父类引用指向子类对象.
注意:抽象类由于不能创建对象.就造成了本类的方法不能调用,解决的方法有两种1) 父类的引用指向子类对象来实现. Calender c = Calender.getInstance()
2)就是创建一个子类的对象调用子类重写的方法.
1. 获取日期的方法.
static Calendar getInstance()//获得一个默认时区和语言环境的日历
int get(intfield) //返回给定日历字段的值
2. public void add(intfield,int amount)//对指定字段相加或相减.
public final void set(int year,intmonth,int date)//修改指定字段.
集合
1. 数组和集合存储引用数据类型,存的都是地址值
2. 集合框架
* A:集合的由来
*数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少
*B:数组和集合的区别
* 区别1:
* 数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值
*集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象
例:100 地层相当于 new Integer(100) 装箱在集合里面引用相当广泛.
* 区别2:
*数组长度是固定的,不能自动增长
* 集合的长度的是可变的,可以根据元素的增加而增长(部分集合的底层是用数组来实现的)
*C:数组和集合什么时候用
*1,如果元素个数是固定的推荐用数组
*2,如果元素个数不是固定的推荐用集合
有的人就想不管是不是固定的都用集合,完全可以但是会浪费空间.而且效率低.
*D:集合继承体系图 (自己画)
3. Collection 集合 它的方法在开发中都会使用.底层是数组实现
一.Collection 的方法 以及 ArrayList方法
1> boolean add(E e) 给集合添加元素 .添加的是一个个对象.
在List集合中可以储存重复元素所以任何类型都是返回true.Set集合中不可以储存重复元素. 由于集合只能储存引用数据类型所以基本数据类型会自动装箱.Object类是任何类的直接接或间接的父类.
2>boolean remove(Object o) 删除集合中的指定元素.
boolean removeAll(Collection c) // 删除交集.
booleanretainAll(Collection c) 取交集 如果改变是true未改变 false
3>voidclear() 清空集合.
4>booleancontains(Object o)是否包含指定元素
booleancontainsAll(Collection c)//取交集 判断是否包含
5>booleanisEmpty()判断是否为空
6> int size()获取集合中的元素个数.
7.Object[] toArray();把集合转换成任何类型的数组
遍历数组:其实就是依次获取集合中的每一个元素 遍历
二. Iterator接口 迭代器.(遍历集合) ArrayList中是继承了Collection中的
Boolean hasNext() 判断是否有元素可以迭代.则返回true,会指针后移
E next() (只能调用一次,调用多次指针会向后移动多洗)获取迭代的下一个元素.这个会指针后移获取下一个元素
上面两个方法是迭代的黄金组合 用while循环.
集合框架(迭代器的原理及源码解析)(了解)
A:迭代器原理
迭代器原理:迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同
的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可
* B:迭代器源码解析
*1,在eclipse中ctrl +shift + t找到ArrayList类
*2,ctrl+o查找iterator()方法
*3,查看返回值类型是new Itr(),说明Itr这个类实现Iterator接口
*4,查找Itr这个内部类,发现重写了Iterator中的所有抽象方法
三. List 接口
1> List集合中的特有功能概述
*void add(intindex,E element)//指定位置插入指定元素,别的元素向后移.
*E remove(intindex) //删除指定位置(索引)的元素.返回获取这个元素
*E get(intindex) //获取指定位置的元素.并返回获取这个元素遍历List特有的遍历方法.
*E set(int index,E element)替换指定位置的元素.
2> 15.10_集合框架(List集合存储学生对象并遍历)
*A:案例演示
* 通过size()和get()方法结合使用遍历。
Listlist = new ArrayList();
list.add(newStudent("张三", 18));
list.add(newStudent("李四", 18));
list.add(newStudent("王五", 18));
list.add(newStudent("赵六", 18));
for(inti = 0; i < list.size(); i++) {
Students = (Student)list.get(i);
Sys.out.println(s.getName()+ "," + s.getAge());
}
四. ListIterator集合框架(不常用知道就可以)
1> 迭代的时候添加元素就会 -并发修误.ConcurrentModificationException
就要用到 ListIterator迭代器.(这是用迭代器的黄金组合)
1/ void add() 添加到迭代器中 (List特有的方法).
2 /hasPrevious
()
逆向判断.
previousIndex
()
逆向打印 (了解 )
五. 集合框架(Vector的特有功能) (了解只在面试题中出现)
Vector 被list完全替代掉了 开发不会在用.
* A:Vector类概述
* B:Vector类特有功能
* public void addElement(E obj)
* public E elementAt(int index)
* public Enumeration elements()
* C:案例演示
* Vector的迭代
Vector v = new Vector(); //创建集合对象,List的子类
v.addElement("a");
v.addElement("b");
v.addElement("c");
v.addElement("d");
//Vector迭代
Enumeration en = v.elements(); //获取枚举
while(en.hasMoreElements()) { //判断集合中是否有元素
System.out.println(en.nextElement());//获取集合中的元素
}
六. List三个子类的特点
集合框架(List的三个子类的特点)
A:List的三个子类的特点
ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector: (只会出现在面试题中)
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)
LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
Vector和ArrayList的区别
Vector是线程安全的,效率低
ArrayList是线程不安全的,效率高
共同点:都是数组实现的
ArrayList和LinkedList的区别
ArrayList底层是数组结果,查询和修改快
LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
共同点:都是线程不安全的
B:List有三个儿子,我们到底使用谁呢?
查询多用ArrayList
增删多用LinkedList
如果都多ArrayList (开发用的最多)
作业: 1:集合的由来? 2:集合和数组的区别? 3:Collection集合的功能概述?
4:Collection集合存储字符串并遍历?(迭代器) 5:Collection集合存储自定义对象并遍历?(迭代器) 6:List集合的特有功能? 7:List集合存储字符串并遍历?(迭代器和普通for) 8:List集合存储自定义对象并遍历?(迭代器和普通for) 9:并发修改异常出现的原因?解决方案?
10:常见的数据结构的特点?
数组:
链表:
11:List集合的子类特点
ArrayList:
Vector:
LinkedList:
12:List的三个儿子你准备使用谁?请说明理由。
七. ArrayList 方法的底层编写的原理.(删除重复元素)
案例1: 去除ArrayList中重复字符串元素方式 新数组去替换老数组
案例2: 去除ArrayList中自定义对象的重复字符串元素方式
结论: contains 和remove方法的底层都是 用equals方法实现的.所以我们在使用自定义对象当做参数传递时要删除重复元素时必须重写自定义类的equals方法.
八. LinkedList 底层是链表实现的.
1. 特有的方法.
1> public void addFirst(E e)及addLast(E e)//在头加 及 在尾加.
2> public E getFirst()及getLast() //获取第一个元素 及 获取最后一个元素
3> public E removeFirst()及public EremoveLast()
//删除第一个 及 删除 最后一个
4> public E get(int index); //获取指定索引的元素.
2. 栈和队列的区别
栈: 是先进后出. 队列:是先进先出.
作业: 用 LinkedeList 模拟栈和队列.
九. 泛型 Generic-集合框架(泛型概述和基本使用)(会用就行)
1. :泛型好处
1>提高安全性(将运行期的错误转换到编译期)
2> 省去强转的麻烦
2. C:泛型基本使用
1> <>中放的必须是引用数据类型
2>:泛型使用注意事项
3> 前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)
4> 泛型一般不定义为Object因为没有意义.
成为类的泛型时.例: class 类名<泛型类型>
成为方法的泛型时.
一般情况下方法的泛型和类的泛型一致.若不一致就必须要声明自己的型.
但是静态方法必须要声明自己的泛型.
例: public<泛型> 返回类型 方法名 (泛型类型 变量名)
3. 泛型高级之通配符
A:泛型通配符>
*任意类型,如果没有明确,那么就是Object以及任意的Java类了
*B:? extends E
* 向下限定,E及其子类
*C:? super E
* 向上限定,E及其父类
十. 集合框架(增强for)(重点掌握)JDK1.5的新特性
1)好处: 简化数组和Collection集合的遍历 它的底层
只要可以用迭代器的迭代的类就一定可以用增强for循环.
2)原理: 底层依赖的是迭 代器(Iterator) 相当于把迭代器封装了起来.
3)格式:
for(元素数据类型变量 : 数组变量或者Collection集合变量) {
syso(i)
}
作业: 数组,集合存储元素用增强for遍历
4) 集合框架(三种迭代的能否删除重复元素) (重点掌握)
1>普通for循环,可以删除,但是索引要 – (减减)
2>迭代器,可以删除,但是必须使用迭代器自身的remove()方法,否则会出现并发修改异常(建议查看API)
3>增强for循环不能删除
十一: 静态导入 ,看懂就可以 JDK1.5的败笔 (掌握 面试会考)
1. 格式: import static 包名….类名.方法名
2. 注意事项
方法必须是静态的,如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。
十二 : 集合框架(Changeable可变参数)jdk1.5(掌握)
1> 格式 (可变参数其实就是数组.)
修饰符 返回值类型 方法名(数据类型… 变量名){}
例:publicint[] get(int … arr){ }
2> 注意事项:
这里的变量其实是一个数组
如果一个方法有可变参数,并且有多个参数,那么,可变参数必须放在最后一个
例: public void get(int x,string s,int … arr){}
十三. 数组与集合相互转换.(掌握)
1> 数组-à集合
固定格式:List
注意事项: 基本数据类型转换成集合,会将数组当做一个对象. 要想基本数据类型转换成集合,就必须是基本数据类型的包装类.
例: 错误写法:int[] a = {1,2,3,4}
正确写法:Integer[] a = {1,2,3,4};
List
2> 集合---à数组
方法1: Object[] obj = 集合变量.toArray(); 无参的转换
方法2: T[] t = 集合变量.toArray(T[]a); 有参的转换
例: Integer[] it = list.toArray(new Integer[参数个数]);
注意: [参数个数] 如果数组长度小于或等于集合的size时,转换后就会等于集合的长度.如果数组的长度大于size,分配的长度就和指定的长度一样. (最好要练习练习)
十四: 集合嵌套之ArrayList嵌套ArrayList(掌握)
格式: 例:for(Array
例: ArrayList
Array
a1.add(newParson(“小”,12));
a1.add(newParson(“小小”,13));
Array
a2.add(newParson(“大”,22));
a2.add(newParson(“大大”,23));
list.add(a1); list.add(a2);
for(Array
十五 : set 接口
1> 由于set是Collection的子接口.所以Collection的方法set都有.
而且Set没有特有的方法
3>set的特点:无索引, 无重复元素.
Set接口无重复元素的本质是:地层调用了hashcoude()和equals()方法.
作业: HashSet存储字符串并遍历
2> 这里用set的实现类 HashSet 来描述 Set类.
(1)HashSet 实现集合类.
无索引, 无重复元素,存和取无序
1. 作业:存储自定义对象,并保证元素唯一性(非常重要)
必须重写hashCode()和equals()方法
记住:内存中只有hashcode()值是一样的时候才会调用equals方法.不然永远都不会调用 比如:火车上自己的座位上有人坐了才回去比较.
开发中可以由Eclipse自动生成
拓展:为什么Eclipse自动生成的hashcoude()中 ,常量是31呢?
答:1) 31是个质数,较少公约数,2) 31不大也不小不会超出int取值范围.
3) 31刚还是2向左移5位再减1取得更好算.
publicbooleanequals(Object obj) {
if (this ==obj) //传入的对象等于本对象
returntrue;
if (obj ==null) //传入的对象为空.空指针异常
return false;
if(getClass() !=obj.getClass())//本对象的字节码文件不等于
returnfalse; 传入文件的字节码文件
Parsonother =(Parson)obj;//上面都满足了就可以向下转型了.
if (age !=other.age) //如果本对象的年龄不等于传入的年龄
returnfalse;
if (name ==null) { //如果本对象的名字为空.
if (other.name !=null)//传入的对象不为空
returnfalse;
} elseif (!name.equals(other.name))//名字不相等
returnfalse;
returntrue;
}
上面不用自己写,但是原理要掌握,代码优化
2. HashSet原理
* 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
* 当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象
* 如果没有哈希值相同的对象就直接存入集合
* 如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存
3.将自定义类的对象存入HashSet去重复
* 类中必须重写hashCode()和equals()方法
*hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
*equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储
(1.1) LinkedHashSet集合类
1) LinkedhashSet的特点
1.因为是hashset的子类,所以也能保证元素唯一,与hashset原理一样 .方法也是一样的
2. 底层是链表实现的,是Set集合中唯一一个能保证怎么存就怎么取的集合对象.
作业: 产生10个1-20之间的随机数要求随机数不能重复
作业: Scanner从键盘读取一行输入,去掉其中重复字符, 打印出不同的那些字符
作业:将集合中的重复元素去掉 addAll();
(1.2)TreeSet 集合类 (底层是二叉树) 很重要
1) TreeSet的特点 (重点对自定义类的操作的关键就是重写CompareTo)
1.底层是二叉树—两个叉, 其实就是(compareTO)
存储的特点:小的存在左边(负数),大的存在右边(正数)相等就不存(0)
2.对对象排序,也保证了对象的唯一.
3.
当compareTo的方法返回值为0时就不存.
当compareTo的方法返回值为正数时排右边
当compareTo的方法返回值为负数时排左边..
2)
自然排序 (构造器为空) (按照字典顺序排列) (Comparable )
1.用自定义对象时,必须重写Comparable 接口的compareTo
的方法
.
要不然排不了序.格式:ComparTo(应用类型 类型变量)
2.Comparable
的compareTo()的方法.
自定义类的操作的关键就是重写CompareTo方法.
特点:
1. TreeSet
类的add()方法中会把存入的对象提升为Comparable类型(所以自定义对象就必须重写
CompareTo方法)
2.
调用对象的compareTo()方法和集合中的对象比较
3.
根据compareTo()方法返回的结果进行存储
作业
: TreeSet
存储自定义对象并遍历练习1(按照姓名排序)
TreeSet
存储自定义对象并遍历练习2(按照年龄排序)
TreeSet
存储自定义对象并遍历练习2(按照姓名的长度排序)
3)
比较器排序 (构造为比较器) Comparator 特点
1.
创建TreeSet的时候可以制定 一个Comparator(比较器)
例:
TreeSet ts = new TreeSet(
比较器对象)
2.
如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
3.
add()
方法内部会自动调用Comparator接口中compare()方法排序
4.
调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
4)
两种方式的区别 (主要看创建的TreeSet的对象的构造)
1.TreeSet
构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
2.TreeSet
如果传入Comparator, 就优先按照Comparator
作业
:
在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复 (很重要) 多练
public static voidmain(String[] args) {
ArrayList
list.add("ccc");
list.add("ccc");
list.add("aaa");
list.add("aaa");
list.add("bbb");
list.add("ddd");
list.add("ddd");
sort(list);
System.out.println(list); }
/* * 对集合中的元素排序,并保留重复
* 1,void
*2,List
*/
public static void sort(List
TreeSet
Comparator
@Override
public int compare(String s1, String s2) {//重写compare方法
int num = s1.compareTo(s2); //比较内容
return num == 0? 1 : num; }}); //如果内容一样返回一个不为0的数字即可
ts.addAll(list);//将list集合中的所有元素添加到ts中
list.clear(); //清空list
list.addAll(ts);//将ts中排序并保留重复的结果在添加到list中
作业: 从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入: helloitcast程序打印:acehillostt
作业: 程序启动后, 可以从键盘输入接收多个整数, 直到输入quit时结束输入. 把所有输入的整数倒序排列打印