------- android培训、java培训、期待与您交流! ----------
API (1)
String类
• 每个用双引号括起来的字符串都是一个对象
• new String() 等于”” String s1 = “abc”; s1代表一个对象 String s2 = new String(“abc”); s2在内存中有两个对象 二者的地址值不同,但是equals的结果为真,因为String类复写了Object类中的equals方法,用于判断字符串是否相等 • 字符串一旦初始化就不可以改变 • String s1 = “abc”; String s2 = “abc”; s1 == s2 结果为true 当内存中已经存在相同的字符串时不需要创建新的对象 ▸ 常见功能 StringMethodDemo.java ▸ 获取 • 字符串中包含的字符数,也就是长度:int length() 注意与数组的长度的区别:数组的长度是属性,没有() • 获取某个位置上的字符:char charAt(int index) 访问到不存在的脚标是会发生StringIndexOutOfBoundsException • 根据字符获取在字符串中的位置:int indexOf(int ch) 接收的是字符的ASCII码 返回的是在字符串中第一次出现的位置 如果没有找到返回-1 int indexOf(int ch, int formIndex):从指定位置开始搜索 int indexOf(String str) int indexOf(String str, int formIndex):字符串 int lastIndexOf():反向索引 ▸ 判断 • 是否包含一个子串:boolean contains(str) 用indexOf也可以实现该功能,返回-1说ing不存在 • 是否有内容:boolean isEmpty() 判断长度是否为0 • 是否是以指定内容开头:boolean startsWith(str) • 是否是以指定内容结尾:boolean endsWith(str); • 内容是否相同:boolean equals(str) • 判断内容是否相同并忽略大小写:boolean equalsIgnoreCase() ▸ 转换 • 将字符数组转成字符串 构造函数String(char[]) String(char[], offset, count) 将字符数组中的一部分转成字符串 静态方法 static String copyValueOf(char[]) static String copyValueOf(char[] data, int offset, int count) static String valueOf(char[]) • 将字符串转成字符数:char[] toCharArray() • 将字节数组转成字符串 String(byte[]) String(byte[], offset, count) • 将字符串转成字节数组:byte[] getBytes() • 将基本数据类型转换成字符串 String valueOf(int) String valueOf(double) 可以写成3+”” • 特殊:字符串和字节数组在转换操作过程中是可以指定编码表的 • 替换 String replace(oldChar, newChar) 返回一个新的字符串,原字符串不会改变(也无法改变) 如果要替换的字符不存在,则返回原字符串 也可以替换字符串 • 切割:String[] split(regex) • 子串:获取字符串的一部分 String subString(begin) String subString(begin, end) ▸ 转换,去除空格,比较 • 将字符串转成大写或小写 String toUpperCase String toLowerCase • 将字符串两端的多个空格去除:String trim • 对两个字符串进行自然顺序的比较:int compareTo(String) 等于返回0 小于返回负数 大于放回正数:相减 ▸ 练习 StringTest.java 要求能手写代码! • 实现trim功能 while(pos<=x && s.charAt(pos)==‘ ‘) pos++; int x = s.length()=1; while(pos<=x && s.charAt(x) == ‘ ‘) x--; str.subString(start, end+1); ▸ 反转字符串 • 将字符串变成数组:toCharArray • 对数组反转 for(int start=0, end=arr.length-1; start<end; start++,end--) { swap(arr, start, end); } • 将数组变成字符串:new String() • 注意:java取区间时一般包含头不包含尾 ▸ 获取一个字符串在另一个字符串中出现的次数 • 第一种: while((index=str.indexOf(key))!=-1) subString • 第二种方式: while(str.indexOf(key, index) != -1) index = index+key.length(); • 不建议用split方法,因为如果要找的字符串在开头,会切出多一个空字符串 • 获取两个字符串中最大相同的子串 for(int x=0; x<s2.length(); x++) { for(int y=0,z=s2.length()-x; z!=s2.length()+1) { String temp = s2.subString(y,z); …
StringBuffer
• 是一个容器,长度可以改变StringBufferDemo.java
且可以直接操作多中数据类型
最终会通过toString方法变成字符串
▸ 存储
• StringBuffer append() 将制定数据作为参数添加到已有数据的的结尾
• StringBuffer insert(offset, 数据) 将数据插入到制定位置
• 可以不停.append():方法调用链
▸ 删除
• StringBuffer delete(start, end) 包含start不包含end
• StringBuffer deleteCharAt(index) 删除指定位置的字符
▸ 清空缓冲区
• sb = new StringBuffer();
• sb.delete(0, sb.length());
▸ 获取
• char charAt(int index)
• int idnexOf(String str)
• int lastIndexOf(String str)
• int length()
• String subString(int start, int end)
▸ 修改
• StringBuffer replace(int start, int end, String str)
• void setCharAt(int index, char c) 无返回值
• 反转 StringBuffer reverse
• void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将缓冲区中指定数据存储到制定数组中基本数据类型对象包装类
IntegerDemo.java • byte Byte short Short int Integer long Long boolean Boolean float Float char Character • Integer MAX_VALUE 2147483647 MIN_VALUE Integer复写了equals方法,是数值比较 ▸ 最常见作用是基本数据类型和字符串类型之间的转换 • 基本数据类型转字符串 基本数据类型值+”” 基本数据类习惯.toString(基本数据类型值) ▸ 字符串转成基本类型 • 转成整数 Integer.parseInt 必须传入数字格式的字符串 NumberFormatException • xxx a = xxx.parsexxx(Sring); 静态调用方式 • Integer i = new Integer(“123”); Integer的构造函数可以传入字符串,理解为字符串表示的数字 int num = i.intValue(); 对象调用方式 ▸ 进制转换 • 十进制—>其他进制 toBinaryString() toHexString() toOctalString() • 其他进制 —> 十进制 parseInt(String, radix) ▸ 1.5新特性 • 自动装箱/拆箱 Integer x = 4; x = x + 2; 结果还是对象 • 如果数值在byte范围内并且已存在,则不会开辟新的空间 Integer a = 127; Integer b = 127; a==b 结果为true如果128,超过了byte的范围(-128~127),则需要开辟新空间,结果为false集合类
• 可变长度 只要是对象就能存储 ▸ 集合框架 ▸ Collection ▸ List:元素有序且可以重复,因为该集合有索引 ▸ List的方法 特有方法:可以操作脚标 ▸ 增• add(index, element):在指定位置添加元素 • addAll(index, Collection) • 删:remove(index) • 改:set(index, element) ▸ 查• get(index) • indexOf() • subList(from, to) ▸ listIterator() 也可以用for循环加上get方法取元素 • 在迭代过程中添加或删除元素 • CurrentModificationException 并发操作:迭代器和集合本身同时对同一个元素进行操作 集合的迭代器只有判断,取出,删除操作,所以需要迭代器中有更多对元素操作的功能。如添加,修改 ▸ ArrayList:底层数据结构为数组,查询速度快,增删稍慢,线程不同步 初始容量为10,超过10之后,new一个容量多50%的搬进去 ▸ 练习:去除ArrayList中重复的元素 ArrayListTest.java • 定义一个临时容器 • 迭代源容器 • 在迭代器中调用next()一次就要用hasNext()判断一次 ▸ 练习:将自定义对象作为元素存储到ArrayList中并去重 ArrayListTest2.java▸ 思路• 对人描述,将数据封装进人对象• 定义容器将人存入 • 取出 • List集合判断元素是否相同,依据的是元素的equals方法;包括contains,remove方法也调用的是equals方法 ▸ LinkedList:底层为链表结构,增删速度很快,查询慢 LinkedListDemo.java • 特有方法 addFirst() addLast() getFirst() getLast() 获取元素但不删除 removeFirst() removeLast() 获取元素并删除 如果集合没有元素会出现NoSuchElementException pollFirst() pollLast() 这两个不会出现该Exception,如果没有元素会返回null ▸ 练习:使用LinkedList模拟一个堆栈或者队列数据结构 LinkedListTest.java 堆栈:先进后出;队列:先进先出 ▸ Vector:底层为数组结构,线程同步,被ArrayList替代 • addElement() elementAt() … • Vector的枚举:elements VectorDemo.java 就是Vector特有的取出方式,和迭代器很像,功能重复 Enumeration en = v.elements(); while(en.hasMoreElements()) { en.nextElement(); … ▸ Set:元素无序(存入和取出的顺序不一定一致),不可以重复,没有索引 功能和Collection一致 ▸ HashSet:底层数据结构是哈希表,线程非同步 • 保证元素唯一性:通过hashCode和equals方法完成 如果两个元素哈希值相同,会再比较两个对象是否相同,如果不是就在该哈希值对应的地址顺延存储两个对象 HashSetTest.java 要重写hashCode()和equals()方法 public boolean equals(Object obj) • 判断元素是否存在以及删除等操作依赖的方法是元素的hashCode和equals方法 ArrayList依赖equals ▸ TreeSet:可以对Set集合中的元素进行排序 TreeSetDemo.java:向TreeSet中存入自定义对象 ▸ 排序方式 • 自然顺序/默认顺序:强制让元素具备比较性,实现Comparable接口;需要重写compareTo方法 • 通过构造函数,在集合初始化时就指定比较方式,将比较器对象作为参数传递 TreeSetDemo2.java class MyCompare implements Comparator { public int compare(Object o1, Object o2) • 当两种排序都存在时,以比较器为主• 排序时,当主要条件相同时,要判断次要条件
• 如果要按存入的顺序取出:把compareTo的返回值改成1
• 二叉树:左小右大
▸ 练习:按字符串长度排序 TreeSetTest.java
• 字符串自带的排序方式不是所需要的,所以要自定义比较器
▸ 集合共性方法 CollectionDemo.java
import java.util.*;
• add(object)
• 集合存放的都是地址
• 可以直接打印出集合内的对象
▸ 删除元素
• remove
• clear() 清空
▸ 判断
• contains()
• isEmpty()
• retainAll() 取交集:只会保留和传入集合相同的元素
• removeAll() 去掉相同的元素
▸ 取出元素 • 开发中不只是要把元素打印出来
▸ 迭代器:集合取出元素的方式
• 取出的功能不能用一个方法来描述,所以封装成一个对象;而且不同集合的数据结构不同,所以用对象来描述比较方便
• Iterator() it = xxx.iterator();
while(it.hasNext()) {
it.next();
…
for(Iterator it = al.iterator(); it.hasnext(); ) {
it.netx();
…
▸ 泛型:1.5以后出现的新特性,类型安全机制 GenericDemo.java GenericDemo2.java
▸ 优点
• 将运行时期出现的ClassCastException转移到编译期间
• 避免了强制转换的麻烦
• 格式:通过<>定义要操作的引用数据类型
在API文档中见到<>的都要使用泛型
其实<>就是用来接收类型的,当使用集合时,将集合中要存储的数据类型作为参数传递到<>即可
• Comparator<T>
▸ 泛型类 GenericDemo3.java
• 当类中要操作的引用数据类型不确定时,早期定义Object进行扩展
1.5后使用泛型
• class Demo<T>
▸ 泛型方法 GenericDemo4.java
• 泛型类定义的泛型在整个类中有效,一旦被方法调用就不能改变
• 为了让不同方法可以操作不同不确定的类型,可以把泛型定义在方法上
public <T> void show(T t)
• 可以同时定义泛型类和泛型方法
• 静态方法不可以访问类上定义的泛型,如果静态方法操作的类型不确定,可以定义在方法上
public static <T> void method(T t)
要放在返回值类型前
▸ 泛型接口 GenericDemo5.java
• class *** implements Xxx<String>
• class ***<T> implements Xxx<T>
在建立对象时再明确具体的T
▸ 泛型限定 GenericDemo6.java
▸ 对于不同数据类型的集合和迭代器,可以在一个静态方法上定义泛型使用
• public static void printColl (ArrayList<?> al)
Iterator<?> it =
问号是占位符
不能使用类型的特有方法,比如length()
• public static <T> void printColl (ArrayList<T> al)
Iterator<T> it =
用这种定义方法可以在迭代循环中对数据进行转型以及之后的其他操作
• 建立对象时等号左右泛型的类型必需相同,不可以父类子类
▸ 想要能够接收父类/子类,必须使用泛型限定:
• 上限限定:? extends E
可以接收E或者E的子类
• 下限限定:? super E
可以接收E或者E的父类,比如Comparator接口
GenericDemo7.java
▸ 自定义类时,一般要定义:
• get,set
• hasdCode()
return ***.hashCode()+xxx*34; 保证hashCode的唯一性
• equals()
• toString
• compareTo() implements Comparable<>
▸ MAP集合:键值对
• 特点:一对一对存,要保证键的唯一性
▸ 子类
• HashTable 底层数据结构是哈希表,键值不能为null,线程同步,JDK1.0
• HashMap 底层数据结构是哈希表,键值可以为null,不同步,效率高,JDK1.2
• TreeMap 底层数据结构是二叉树,线程不同步,可以给Map集合中的键进行排序
• 其实Set底层就是使用了Map集合
▸ 方法 MapDemo.java
• 添加
put(K key, V value):存入相同的键时,新的值会替换老的值,并且方法会把老的值返回
putAll(Map<? entends K, ? entends V> m)
• 删除:clear()
• 判断
containsValue()
containsKey()
• 获取
get(Object key):可以用返回值来判断一个键是否存在,null说明不存在(或者值为null,意义不大)
size()
values():获取Map集合中所有的值,返回值为Collection
entrySet()
keySet()
▸ Map集合的两种取出方式 MapDemo2.java
• 原理:将Map集合转换成Set集合,再通过迭代器取值
▸ Set<K> keySet:将Map中所有的键存入到一个Set集合,通过Set的迭代器取出所有的键,再用get方法取对应的值
• Set<String> keySet = map.keySet();
• Iterator<String> it = keySet.iterator();
• while(it.hasNext()) {
String key = it.next(); …
• String value = map.get(key);
▸ Set<Map.Entry<K,V>> entrySet:将Map集合的映射关系存入到Set集合中,该关系的数据类型为Map.Entry
• Set<Map.Entry<String,String>> entrySet = map.entrySet();
• Iterator<Map.Entry<String,String>> it = entrySet.iterator();
• while(it.hasNext()) {
Map.Entry<String,String> me = it.next();
• String key = me.getKey();
String value = me.getValue();
▸ 其实Entry也是一个借口,是Map接口中的一个内部接口
• interface Map {
public static interface Entry {
public abstract Object getKey();
public abstract Object getValue();
• class HaspMap implements Map {
class ** implements Map.Entry {
▸ 练习
• 存取 MapTest.java
• 排序:TreeMap MapTest2.java
class StuNameComparator implements Comparator<Student>
▸ 获取字母出现次数 MapTest3.java
• 扩展知识:一对多映射 MapDemo3.java
▸ 集合框架的工具类
▸ Collections CollectionsDemo.java
• public static <T extends Comparable<? super T>> void sort(List<T> list) 排序
• public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) 返回最大值
• binarySearch
返回插入点-1
具体的实现方法
• fill()
将集合中的元素全部替换 CollectionsDemo2.java
练习:替换部分元素
• replaceAll(List<T> list, T oldValue, T newValue) 替换已有元素
• reverse 反转
• public static <T> Comparator<T> reverseOrder()
返回一个逆向比较器
可以传入一个比较器
• public static <T> List<T> synchronizedList(List<T> list)
返回支持同步的列表
• swap 交换元素
• shuffle 使用默认随机源对指定列表进行置换———把集合的元素随机排列
▸ Arrays:用于操作数组 ArraysDemo.java
• asList:将数组变成List集合
好处:可以使用集合的思想和方法来操作数组中的元素
变成集合后不可以使用集合的增删方法,因为数组的长度是固定的
如果数组中的元素都是对象,那么变成集合时数组中的元素就直接转成集合中的元素
如果数组中有基本数据类型,那么会将整个数组作为集合中的元素存在
▸ Collection接口中的toArray方法 CollectionToArray.java
• 如果指定类型的数组长度小于集合的size,那么该方法内部会创建一个新的数组,长度为集合的size
如果数组长度小于size,那么会使用传递进来的数组,所以最好传入一个长度刚好的数组
• 集合变数组的原因:限定对元素的操作▸ jdk1.5新特性▸ 增强for循环 jdk1.5开始 ForEachDemo.java
• for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
• 只能取出不能修改元素
迭代器除了遍历还能remove集合中元素,如果使用List还可以在遍历过程中进行增删改查
• 高级for循环的局限性:必须有被遍历的目标
建立遍历数组时使用传统for循环,因为可以对脚标进行操作
▸ 可变参数 jdk1.5开始 ParamMethodDemo.java
• 隐式地将参数封装成数组
• 使用时注意要把可变参数放在参数列表的最后
▸ 静态导入 StaticImport StaticImpor.java
• import static java.util.Array.*; 导入Arrays类中的所有静态成员
• 当类重名时需要指定具体的包名,当方法重名时需要制定具备所属的对象或类