1、StringBuffer(JDK1.0后,适用于多线程)
(1)字符串缓冲区,存储数据的容器
(2)特点
- 长度可变,线程安全
- 可以存储不同类型的数据
- 最终转化成字符串使用(“20”是“二零”,不是“二十”)
- 可以对字符串修改
(3)具备的功能
- 添加(除byte和short类型外)append(),insert()
StringBuffer append(data) //可以连续调用append
StringBuffer insert(int offset, data) //在指定位置处插入指定类型数据
StringBuffer sb = new StringBuffer() //默认存储16个字符
- 删除
StringBuffer delete(int start, int end) //包含头,不包含尾
StringBuffer deleteCharAt(int index) //删除指定位置的元素
sb.delete(0,sb.length()); //清空缓冲区
- 修改
StringBuffer replace(int start, int end, String str) //指定替换范围
void setCharAt(int index, char ch) //替换某个字符
- 查找
int indexOf(String str)
int indexOf(String str, int fromIndex)
int lastIndexOf(String str)
int lastIndexOf(String str, int fromIndex)
- 设置字符序列长度
void setLength(int newLength)
- 获取子串
String substring(int start)
String substring(int start, int end)
- 字符串反序
StringBuffer reverse()
2、StringBuilder(JDK1.5后,适用于单线程)
(1)与StringBuffer不同,StringBuilder不保证同步,多线程不安全,其他用法相同,适用于单线程,速度更快,提高效率。
(2)速度快的原因?
- 因为StringBuffer中,多线程情况下,在append和delete操作时,需要同步避免出现问题,利用同步代码块,在单线程的情况下,需要判断锁,降低效率,故引入StringBuilder,在单线程情况下,不用判断锁,提高效率,速度更快。
class StringBuffer
{
Object obj;
public StringBuffer append(int x)
{
synchronized(obj)
{
}
}
public StringBuffer delete(int start,int end)
{
synchronized(obj)
{
}
}
}
3、集合
(1)为什么出现?
对象对特有数据进行封装,对象多了,需要存储,这就需要集合了。
(2)集合与数组的区别?(集合的特点)
- 集合是存储对象的容器
- 集合的长度是可变的
- 集合不可以存储基本数据类型值。
(3)集合容器因为内部数据结构不同,有多种具体容器,不断向上抽取,形成集合框架,框架的顶 层,就是Collection接口
(4)Collection中的方法
- 添加
boolean add(E e)
boolean addAll(Collection<? extends E> c)
- 删除
boolean remove(Object obj) //会改变集合长度
boolean removeAll(Collection<?> c) //删交集
void clear()
- 判断
boolean contains(Object obj)
boolean containsAll(Collection<?> coll)
boolean isEmpty() //判断集合中是否含有元素
- 获取
int size()
Iterator<E> iterator() //迭代获取集合中的元素,迭代器
//该对象必须依赖于具体容器,因为每一个容器的数据结构都不同,所以该迭代器对象是在容器
//中进行内部(内部类)实现的。对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的
//迭代器的对象即可,也就是iterator
//Iterator接口就是对所有的Collection容器进行元素取出的公共接口
- 其他
boolean retainAll(Collection<?> c) //取两个集合的交集到当前集合中
Object[] toArray() //将集合转化为数组
4、List和Set
(1)List
- 有序(存入和取出顺序相同)
- 元素都有索引(角标)
- 元素可以重复
(2)Set
- 元素不重复,一般无序
5、List常用子类(实现了List接口的类)
(1)Vector:内部是数组数据结构,是同步的。增删、查询都很慢(同步降低效率)
(2)ArrayList:内部是数组数据结构,不同步,替代了Vector。查询的速度快(存储空间连续,增删元素,牵一发而动全身)
(3)LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快
(4)获取Vector对象所有元素的方法:迭代器Iterator(iterator方法)和枚举器Enumeration(elements方法)
(6)LinkedList有一系列操作头(First)和尾(Last)的方法。
(7)ArrayList存储自定义对象时,注意强制类型转换。
(8)基本数据类型传递给引用类型时存在在自动装箱,基本数据类型与引用类型做运算时会拆箱。
(9)Set接口中的方法与Collection一致,考虑实现该接口的子类——HashSet和TreeSet
(10)HashSet
- 内部数据结构是哈希表
- 不同步
- 使用iterator获取元素,但不保证迭代顺序(输出顺序是按照一定算法得到的),元素不重复
(11)哈希表确定元素是否相同
- 先判断两个元素的哈希值是否相同,如果相同,再判断两个对象的内容是否相同
- 判断哈希值,利用对象的hashCode方法,判断内容,利用equals方法
- 如果哈希值不相同,不用再判断内容(不用再使用equals方法)
(12)HashSet存储自定义的对象时,也要考虑强制类型转换。可以覆盖hashCode和equals方法,将所有对象的属性(以及所对应的hashCode)考虑进来稳妥些。
(13)不同的数据结构判断元素相同的依据不同,ArrayList是根据equals,HashSet是hashCode和equals
(14)contains和remove都用到equals方法进行判断
(15)LinkedHashSet作为HashSet子类,可以实现元素有序(存取顺序一致)和不重复(唯一)
(16)TreeSet使用元素的自然顺序对Set集合中的元素排序,不同步,元素也不能重复;判断元素唯一的方法就是根据比较方法返回的结果是否为零,是,该元素不存。(覆写compareTo方法,注意对象强制类型转换以及比较条件的主次)
- TreeSet对元素排序方式一:让元素自身具备比较功能,实现Comparable接口,覆盖compareTo 方法(一个参数)
public int compareTo(Object o)
{
//比较姓名和年龄,年龄相同时再考虑姓名,不用if-else
Person p = (Person)o;
int temp = this.age - p.age;
return temp == 0?(this.name.compareTo(p.name)):temp;
}
- 如果不按照对象的自然顺序排序,如果对象不具备自然顺序,怎么办?
- 可以使用TreeSet集合第二种排序方式——让集合自身具备比较功能,定义一个类,实现Comparator接口,覆盖compare方法(两个参数),并将该类的对象作为参数传递给TreeSet构造函数
- 确切地说,TreeSet对元素进行排序,要求元素自身已实现比较算法(方式一),如果元素没有实现,就需要自定义,或者让TreeSet自身具有比较功能(方式二)。
TreeSet ts = new TreeSet(new ComparatorByName());
- 如果对象自身具备比较功能,但集合也有比较器,这是选择使用集合的比较器进行元素比较,比较器Comparator更常用(父类定义了比较器,子类也可以用来比较),Comparable是对象默认具备的比较功能。Comparator要保证存取顺序一致,还需要return 1或者-1.
- TreeSet内部数据结构是二叉树
(17)Map一次添加一对元素,Collection一次添加一个元素;Map称为双列集合,Collection是单列集合;Map集合存储的键值对;Map集合必须保证键的唯一性;Map没有迭代器
(18)Map常用方法
- 添加
value put(K key, V value) //将指定的值与该映射中的指定键相关联
- 删除
void clear() //从该Map中删除所有的映射
value remove(Object key) //根据指定的键删除键值对
boolean remove(Object key, Object value) //删除指定的键值对
- 判断
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
- 获取
value get(Object key) //根据键获取值,如果没有该键返回null,可以根据返回null
//判断是否包含指定键
int size() //获取键值对的个数
(19)Map重点方法
- keySet
Set<K> keySet() //返回Map中包含所有键的Set集合
- 取出Map中所有的元素,方式一:利用keySet
//方法:先通过keySet获取Map中所有键的Set集合,然后根据Set集合的迭代器获取
//每一个键,再根据键获取对应的值
- entrySet
Set<Map.Entry<K,V>> entrySet() //返回此Map中包含的映射的Set视图。
//由于Map没有迭代器,但可以将Map转化为Set,利用迭代器获取元素,该方法将键和值的
//映射关系作为对象存储到Set集合中,而这个映射关系类型就是Map.Entry类型
- 取出Map中所有的元素,方式二:利用entrySet
Set<Map.Entry<Integer,String>> es = map.entrySet();
Iterator<Map.Entry<Integer,String>> it = es.iterator();
//Iterator<Map.Entry<Integer,String>> it = map.entrySet().iterator();
while(it.hasNext())
{
Map.Entry<Integer,String> me = it.next();
//调用Map.Entry中的方法获取键和值
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::"+value);
}
- values
Collection<value> values(); //value可以不唯一
(20)Map的常用子类
- Hashtable
//内部数据结构是哈希表,是同步的,不允许为null的键和值
//其实现子类Properties,用来存储键值对型的配置文件的信息,可以和IO技术结合
- HashMap
//内部结构是哈希表,不同步,允许为null的键和值
- TreeMap
//内部结构是二叉树,可以对Map集合中的键排序
- LinkedHashMap
//可以保证存取顺序一致
- 练习:获取字符串中每个字母出现的次数
public class MapTest
{
public static void main(String[] args)
{
String str = "fjgdjvbfgbacabdfj";
String s = getCharCount(str);
System.out.println(s);
}
public static String getCharCount(String str)
{
//将字符串变成字符数组
char[] cr = str.toCharArray();
//定义Map集合表,考虑Map集合存储的元素类型所对应的包装类
Map<Character,Integer> map = new TreeMap<Character,Integer>();
for(int i=0;i<cr.length();i++)
{
//显示字母
if(!(cr[i]>='a' && cr[i]<='z' || cr[i]>='A' && cr[i]<='Z'))
continue;
//将数组中的字母作为键查Map表
Integer value =map.get(cr[i]);
//判断value是否为null
if(value==null)
map.put(cr[i],1);
else
map.put(cr[i],value+1);
}
return mapToString(map);
}
public static String mapToString(Map<Character,Integer> map)
{
StringBuilder sb = new StringBuilder();
Set<Map.Entry<Character,Integer>> me = map.entrySet();
Iterator<Map.Entry<Character,Integer>> it = me.iterator();
while(it.hasNext())
{
Map.Entry<Character,Integer> mp = it.next();
Character key = mp.getKey();
Integer value = mp.getValue();
sb.append(key+"("+")"+value);
}
return sb.toString();
}
}
- Map在有映射关系时,可以优先考虑,在查表法中较为常用