Java笔记二十 集合框架Set和List以及Map知识总结

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在有映射关系时,可以优先考虑,在查表法中较为常用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值