Java集合框架

113 阅读3分钟

Set

无序不可重复
Set相当于只有key,没有value的Map
通常用来去除重复元素

  • HashSet

    只是对HashMap的简单封装

    1. 不能保证元素的顺序
    2. 线程不同步,需通过代码保证同步
    3. 元素值可以是null

    存储原理: 当向HashSet存储一个元素时,HashSet会调用该对象的hashCode()方法得到其hashCode,然后根据hashCode决定该对象的存储位置。
    两个元素相等的标准: 两个对象通过equals()方法比较返回true,并且hashCode相等
    两个条件有一个不满足,则认为两个对象不相等,可以添加成功。
    hashCode相等,equals()返回false,HashSet会以链式结构将两个对象存储在同一个位置,这会导致性能下降

  • LinkedHashSet

链表HashSet

  • TreeSet

红黑树Set

List

有序可重复,通过索引访问指定位置的元素
转成数组:toArray()
equals()方法:查找元素需要使用

    1.自反性:x.equals(x)返回true
    2.对称性:x.equals(y) == y.equals(x)
    3.传递性:x.equals(y)和y.equals(z)是true,则x.equals(z)也为true
    4.一致性:结果不变
    5.对null的比较:x.equals(null)总是false
  • ArrayList

    数组实现,初始容量10,擅长随即访问
  • LinkedList

    链表实现
  • Vertor(遗留类)

    同步的,也就是线程安全,其余与ArrayList类似

Map

Key值不允许重复,可以为null,添加时已有key,则value覆盖旧value。
内部通过空间换时间的方法,用一个大数组存储所有的value,并根据key直接计算得出value应该存储在哪个索引

  • HashMap

    正确编写hashCode()方法:
        1.equals相同,hashCode必须相同
        2.equals不同,hashCode尽量不同
    遍历:
        1.map.keySet()返回Key的Set
        2.map.entrySet()返回Map.Entry<K, V>,entry.getKey()/getValue()
  • TreeMap

    必须实现Comparable接口,或者传入Comparator对象
  • Properties

    读取配置文件(.properties)

Iterator

遍历List最高效的方式

  • boolean hasNext()
  • E next()
public class Main() {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        List.add("value1");
        //...
        List.add("valuen");
        //List.of("value1", ..., "valuen");//java9
        for(Iterator<String> it = list.iterator(); it.hasNext(); ) {
            //Iterator对象由集合实例调用iterator()方法创建
            String str = it.next();
            System.out.println(str);
        }
    }
}
for(String str : list) {
    System.out.println(str);
    //只要实现了Iterable接口的集合类都可以使用for each循环来遍历
}

Queue

Queue<String> q = new LinkedList<>();
  • PriorityQueue

    Queue<String> q = new PriorityQueue<>();
    
    放入PriorityQueue的元素必须实现Comparable接口,或提供Comparator对象
    public class Main {
        public static void main(String[] args) {
            Queue<User> q = new PriorityQueue<>(new UserComparator());
            // 添加3个元素到队列:
            q.offer(new User("Bob", "A1"));
            q.offer(new User("Alice", "A2"));
            q.offer(new User("Boss", "V1"));
            System.out.println(q.poll()); // Boss/V1
            System.out.println(q.poll()); // Bob/A1
            System.out.println(q.poll()); // Alice/A2
            System.out.println(q.poll()); // null,因为队列为空
        }
    }
    
    class UserComparator implements Comparator<User> {
        public int compare(User u1, User u2) {
            if (u1.number.charAt(0) == u2.number.charAt(0)) {
                // 如果两人的号都是A开头或者都是V开头,比较号的大小:
                return u1.number.compareTo(u2.number);
            }
            if (u1.number.charAt(0) == 'V') {
                // u1的号码是V开头,优先级高:
                return -1;
            } else {
                return 1;
            }
        }
    }
    
    class User {
        public final String name;
        public final String number;
    
        public User(String name, String number) {
            this.name = name;
            this.number = number;
        }
    
        public String toString() {
            return name + "/" + number;
        }
    }
    
  • Deque

    双端队列
    public interface Deque<E> extends Queue<E> {
        ...
    }