java学习笔记 集合

集合

集合框架

  1. 可以动态保存多个对象,使用方便。
  2. 有多种方法,add/remove/set/get
    单列集合


    image.png

    双列集合 kv键值


    image.png

collenction

  1. collection实现子类可以存放多个元素,每个元素可以是Object
  2. 有些collection的实现类,可以存放重复元素,有些不可以
  3. 有些collection的实现类,有些是有序的List 有些不是有序的Set
  4. collection接口没有直接的实现子类,是能过它的子接口Set和List来实现
  5. Collection接口遍历元素方式使用Iterator 迭代器
  6. Iterator对象称为迭代器,主要用于遍历Collection集合中的元素。
  7. 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回 一个迭代器。
  8. Iterator仅用于遍历集合,Iterator本身并不存放对象。
  • List
    • ArrayList 单线程用,线程不安全,但执行效率高。
    • LinkedList 线程不安全 底层实现双向链表和双端队列特点。
    • Vector 线程同步,线程安全。
  • Set 无序,没索引,不允许重复,最多只能有一个null
    • HashSet
    • LinkedHashSet
    • TreeSet
  1. 当我们使用无参构造器,创建TreeSet时,仍然是无序的
  2. 希望添加元素,按时一定方式排序,使用TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)并指定排序规则。
  3. 在底层传给了TreeMap的一个属性comparator


    image.png
TreeSet treeSet = new TreeSet(new Comparator(){
  @override
  public int compare(Object o1, Object o2){
    return ((String) o1).compareTo((String) o2);
}
});

只能用生成器,与for-each遍历。

常用方法:

  1. add: 添加单个元素
  2. remove:删除指定元素
  3. contains:查找元素是否存在
  4. size: 获取元素个数
  5. isEmpty:判断是否为空
  6. clear:清空
  7. addAll: 添加多个元素
  8. containsAll:查找多个元素是否都存在
  9. removeAll: 删除多个元素。
public class Test07 {
    public static void main(String[] args) {

        Collection col = new ArrayList();
        col.add(new Book("天龙八部", "Gorgage", 100.0));
        col.add(new Book("天龙七部", "Gorgage1", 98.0));
        col.add(new Book("天龙六部", "Gorgage2", 56.0));

        for (Object book : col) {
            System.out.println(book);
        }

        Iterator iterator = col.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(next);

        }
    }
}

class Book {
    private String bookName;
    private String name;
    private double price;

    public Book(String bookName, String name, double price) {
        this.bookName = bookName;
        this.name = name;
        this.price = price;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

如果是List接口 还可以增加一种for 循环里面使用get(索引)来遍历。
容量扩展一般按1.5倍来扩展。

底层结构 增删效率 改查效率
ArrayList 可变数组 较低,数组扩容 较高
LinkedList 双向链表 较高,通过链表追加 较低
  1. 如果我们改查的操作多,用ArrayList
  2. 如果我们增删的操作多,选择LinkedList
  3. 一般来说,在程序中。80%-90%是查询,因此大部分情况 下选择ArrayList
  4. 在一个项目中,根据业务灵活选择,也可能这样,一个模块 使用ArrayList,另外一个模块使用LinkedList

LinkedHashSet

  1. LinkedHashSet加入顺序和取出元素、数据的顺序一致
  2. LinkedHashSet 底层维护的是一个LinkedHashMap(是 HashMap 的子类)
  3. LinkedHashSet 底层结构(数组table + 双向链表)
  4. 添加第一次时,直接将 数据 table 扩容到16,存放的结点类型是LinkedHashMap$Entry类型
  5. 数组是 HashMapEntry类型

map

  1. Map与Collection并列存在。用于保存具有映射关系的数据:key-Value
  2. Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
  3. Map中的key不允许重复,
  4. Map中的value可以重复
  5. Map中的key 可以为null, value 也可以为null, 注意key最多只有一个为null,value可以多个
  6. 常用String类作为Map的key
  7. key 和 value之间存在单向一对一关系,即通过指定的key 总能找到对应的value

Map方法:

  • put:添加
  • remove:根据键删除
  • get:根据键获取值
  • size:获取元素个数
  • isEmpty:判断个数是否为0
  • clear:清除
    -containsKey: 查找键是否存在

Map遍历方法:

public class Test08 {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("Gorgage","marry");
        map.put("Gorgage1","marry1");
        map.put("Gorgage2","marry2");
        map.put("Gorgage3","marry3");
        map.put(null,"marry4");
        map.put("Gorgage5",null);

        Set keySet = map.keySet();
        System.out.println(map.keySet());

        System.out.println("====for-each====");
        for (Object key: keySet
             ) {
            System.out.println(map.get(key));
        }
        System.out.println("====iterator====");
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(map.get(next));
        }

        System.out.println("====map.values====");
        Collection values = map.values();
        System.out.println(values);

        System.out.println("====mmap.entrySet====");
        Set set = map.entrySet();

        for (Object entry:set
             ) {
            //转Map.Entry,向下转型
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey() + "++++"+m.getValue());
        }
        Iterator iterator1 = set.iterator();
        while (iterator1.hasNext()) {
            Object next = iterator1.next();
            //转Map.Entry,向下转型
            Map.Entry m = (Map.Entry)next;
            System.out.println(m.getKey() + "++++"+m.getValue());
        }
    }
}
[null, Gorgage1, Gorgage2, Gorgage, Gorgage3, Gorgage5]
====for-each====
marry4
marry1
marry2
marry
marry3
null
====iterator====
marry4
marry1
marry2
marry
marry3
null
====map.values====
[marry4, marry1, marry2, marry, marry3, null]
====mmap.entrySet====
null++++marry4
Gorgage1++++marry1
Gorgage2++++marry2
Gorgage++++marry
Gorgage3++++marry3
Gorgage5++++null
null++++marry4
Gorgage1++++marry1
Gorgage2++++marry2
Gorgage++++marry
Gorgage3++++marry3
Gorgage5++++null

进程已结束,退出代码0

  • HashMap
  1. Map接口的常用实现类:HashMap / Hashtable和Properties
  2. HashMap是Map接口使用频率最高的实现类。
  3. HashMap 是以 key-value对的方式 来存储数据
  4. key不能重复,但是值可以重复,允许使用null键和值
  5. 如果添加相同的key,则会覆盖原来的key-value,等同于修改
  6. 与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的
  7. HashMap没有实现同步,因此是线程不安全的。

底层机制与HashSet相同,因为HashSet底层是HashMap

  1. HashMap底层维护了Node类型的数组table,默认为null
  2. 当创建对象时,将加载因子(loadfactor)初始化为0.75
  3. 当添加key-value时,能过key的哈希值得到在table的索引,然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,继续判断该元素的key是否和准备加入的key相等 ,如果相等,则直接替换value,如果不相等 要判断是树结果 还是链表结构,做出相应处理。如果添加时发现容量不够 ,则需要扩容。
  4. 第1次添加,则需要扩容table容量为16,临界值(threshold)为12
  5. 以后再扩容,则需要扩容table容量为16,临界值为原来的2倍,即24,依次类推。
  6. 在java8中,如果一条链表的元素个数超过TREEIFY_THRESHOLD默认是8,并且table的大小>= MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)
  • Hashtable
    他继承Dictionary,实现Map接口。
  1. 存放的元素是k-v
  2. hashtable的键值都不能为null,否则会抛出NullPointerException
  3. hashtable使用方法基本和HashMap一样。
  4. hashTable是线性安全的,HashMap不安全
  5. hashtableEntry的方法。
  6. hashTable创建时会有11个空间。
  7. threshold = 8 = 11 * 0.75
  • Properties
  1. Properties 继承Hashtable,并实现Map接口,也是使用一种键值对的形式保存
  2. 他的使用特点和Hashtable类似
  3. Properties 还可以用于从xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改。
  4. xxx.properties文件通常作为配置文件,可参考
  • LinkedHashMap
  • TreeMap
    是TreeSet的底层

collenctions

在开发中,选择什么 集合实现类,主要取决于业务操作特点,然后根据集合实现类特性进行选择

  1. 先判断存储类型(一组对象或一组键值对)
  2. 一组对象:Collection接口
    2.1 允许重复:List
    2.1.1 增删多:LinkedList底层维护了一个双向链表
    2.1.2 改查多:ArrayList底层维护Object 类型的可变数组
    2.2 不允许重复:Set
    2.2.1 无序:HashSet 底层HashMap,维护了一个哈希表,即数组+链表+红黑树
    2.2.2 排序:TreeSet
    2.2.3 插入和取出顺序一致:LinkedHashSet, 维护数组+双向链表
  3. 一组键值对:Map
    3.1 键无序:HashMap 底层哈希表 数组+链表+红黑树
    3.2 键排序: TreeMap
    3.3 键插入和取出顺序一致:LinkedHashMap
    3.4 读取文件 Properties
  4. Collections是一个操作 Set List Map等 集合的工具类
  5. Collections中提供了一系列静态方法对集合元素进行排序、查询和修改
    5.1 reverse(List):反转List中元素顺序
    5.2 shuffle(List): 对List集合元素进行随机排序
    5.3 sort(List): 根据合元素的自然顺序对指定List集合元素按升序排序,
    5.4 sort(List, Comparator): 根据指定的Comparator产生的顺序对List集合元素进行随机
    5.5 swap(List, int, int):将指定List 集合中的i外元素和j 处元素进行交换。
  6. Object max(Collection)根据元素的自然顺序,返回给定集合中的最大元素
  7. Object max(Collection, Comparator)根据Comparator指定的顺序返回给定集合中最大元素
  8. Object min(Collection)
  9. Object min(Collection, Comparator)
  10. int frequency(Collection, Object):返回指定集合中指定元素的出现次数
  11. void copy(List dest, List src)将src中的内容复制到dest中
  12. boolean replaceAll(List list, Object oldVal, Object newVal)使用新值替换List 对象的所有旧值。

你可能感兴趣的:(java学习笔记 集合)