Collection接口

  1. List:有顺序,元素可以重复
  2. Set:没有顺序,元素不可以重复
    Set内部有一个专门排序的算法
    • 所谓的无序不等于随机
    • 所谓的无序指的是没有按照添加的先后顺序,其实内部是做了内部排序的

顺序指的是添加的先后顺序

List

List:数据时有顺序的,数据可以重复
ArrayList集合:内部结构是数组。比较适合做高频率的查找、遍历
LinkedList集合:双向链表。比较适合做高频率的新增和删除

//List<String> list = new LinkedList<>();
LinkedList<String> list = new LinkedList<>();
//添加数据
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//创建对象时用的是多态
//父类对象---->子类引用
//创建出来的对象只能调用父类和子类都有的方法

//在集合头部添加
list.addFirest("z");
//在集合尾部添加
list.addLast("x");
//删除集合第一个元素
list.removeFirst();
//删除集合最后一个元素
list.removeLast();
//根据下标索引获取指定位置的元素
list.get(int index)
List集合的遍历
List<String> list = new ArrayList<>();
1.for循环
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

2.foreach循环
for (String s: list) {
    System.out.println(s);
}

3.迭代器
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
    String s = iterator.next();
    System.out.println(s);
}

Set

Set集合如何确保数据的不重复
->保证数据类型的类要重写hashCode和equals方法
实例如下:

Set<Person> set = new HashSet<>();
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));
set.add(new Person("张三",1001));

System.out.println(set);

上述代码为使数据不重复在Person类中重写hashCode和equals方法

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Person person = (Person) o;

    if (!name.equals(person.name))
        return false;
    return id.equals(person.id);
}

    @Override
public int hashCode() {
    int result = name.hashCode();
    result = 31 * result + id.hashCode();
    return result;
}
TreeSet

排序规则:要排序的对象的类必须实现Comparable接口

Set<Person> tree = new TreeSet<>();
tree.add(new Person("张岳",1001));
tree.add(new Person("李四",1010));
tree.add(new Person("费四",1003));

在Person类中实现Comparable接口,并重写compareTo()方法

 @Override
public int compareTo(Person p) {
    if (this.id > p.id) {
        return -1;
    }
    if (this.id.equals(p.id)) {
        return 0;
    }
    return 1;
}
LinkedHashSet

由于LinkedHashSet的底层是哈希表和链表,所以它与其它的Set集合的区别就是,LinkedHashSet是有序的。使得其在添加数据的同时维护数据的添加顺序,效率比HashSet略低

  1. 哈希表:保证集合的唯一性特点
  2. 链表:保证有序
Set集合的遍历
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(4);
set.add(15);
set.add(38);

//增加for循环
for (Integer integer: set) {
    System.out.println(integer);
}

//迭代器
Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()){
    Integer s = iterator.next();
    System.out.println(s);
}
比较接口

Comparable接口:自然排序,排序规则是固定的
Comparator接口:临时排序
Comparable的compareTo(T)方法只有1个参数,.
Comparator接口的compare(T o1, T o2)方法有两个参数

Map接口

  1. 存储对值K-V key-value
  2. key不能重复,value是可以重复的
  3. 没有顺序(添加的先后顺序)

HashMap内部存储结构:
jdk1.7之前:链表 + 二叉树
jdk1.7及其之后:链表 + 数组 + 红黑树

Map<String, String> map = new HashMap<>();
map.put("1001","张岳");
map.put("1002","赵红兵");
map.put("1003","小北京");
map.put("1004","李四");
map.put("1005","张浩然");
//获取values()值   姓名
System.out.println(map.values());
//获取keySet()     ID
System.out.println(map.keySet());
Hashtable和HashMap的区别
  1. Hashtable是线程同步的,线程安全 HashMap是线程异步的,线程不安全
  2. HashMap的key是可以为null的,Hashtable是不可以为null
Properties:属性

Properties是Hashtable的子类,更多地是用来操作属性文件

迭代中删除元素
public class Ch13 {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("tom");
        names.add("lucy");
        names.add("lucy");
        names.add("lucy");
        names.add("jerry");

        for (int i = 0; i < names.size(); i++) {
            if(Objects.equals(names.get(i),"lucy")){
                names.remove(i);
                // 1.回调指针
                i--;
            }
            if("lucy".equals(names.get(i))){

            }
        }
        // 2.逆序遍历
        for (int i = names.size() - 1; i >= 0; i--) {
            if(Objects.equals(names.get(i),"lucy")){
                names.remove(i);
            }
        }
        // 3.使用迭代器(推荐)万无一失
        Iterator<String> iterator = names.iterator();
        while(iterator.hasNext()) {
            String s = iterator.next();
            if(Objects.equals(s,"lucy")){
                iterator.remove();
            }
        }
        // 4.增强for循环
        for (String s : names) {
            if(Objects.equals(s,"lucy")){
                names.remove(names.indexOf(s));
            }
        }
        System.out.println(names);
    }
}

其他的集合

  1. LinkedHashMap,在HashMap的基础上维护了一个双向链表。
  2. TreeMap:天然支持排序
  3. Collections:Collections是一个工具类
  • 线程安全问题:
  • 迭代器是依赖于集合而存在,在判断成功以后,集合中新增了元素,
  • 迭代器不知道,所以就报错。
  • 解决:
  • 1.迭代器遍历元素,迭代器删除元素
  • 2.普通for循环遍历,集合删除
public class Ch15 {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("tom");
        names.add("lucy");
        names.add("lucy");
        names.add("lucy");
        names.add("jerry");

        for (String s : names) {
            if (Objects.equals(s, "lucy")) {
                names.add(s);
            }
        }
    }
}