集合/容器

当我们需要保存一组一样(类型相同)的元素的时候,我们应该使用一个容器
来存储,数组就是这样一个容器。
数组有什么缺点?
数组一旦定义,长度将不能再变化。
然而在我们的开发实践中,经常需要保存一些变长的数据集合,于是,我们需
要一些能够 动态增长长度的容器 来保存我们的数据。
而我们需要对数据的保存的逻辑可能各种各样,于是就有了各种各样的数据结
构。 Java中对于各种数据结构的实现,就是我们用到的集合。

第一部分主要讲解的是Collection部分,名为单列。
逻辑如图:

集合/容器

需要保存一组一样(类型相同)的元素

Collection(单列)

List:有序,可重复

ArrayList 存储方式为数组,可重复,按添加顺序排列

特点是查询比较快,可以直接用索引查询,但是删除和增加元素比较麻烦

(增加或者删除一个元素时,其他元素位置需要发生改变)




import java.util.ArrayList;

public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        //ArrayList<Integer>arrayList = new ArrayList<>(10);  此时是在创建对象时就已经创建新数组
        arrayList.add(10);//在添加第一个元素时创建新数组
        arrayList.add(1, 0);//指定位置添加元素 后面的元素要往后移动一位
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        arrayList.add(5);
        arrayList.add(6);
        arrayList.add(7);
        arrayList.add(8);
        arrayList.add(9);
        arrayList.add(9);
        //会自动扩容    为原来长度的1.5倍
        arrayList.size();//容量
        arrayList.contains(100);//是否包含一百这个元素,返回值为true或false
        arrayList.clear();//清除
        arrayList.set(3, 9);//在指定位置替换某个元素
        System.out.println(arrayList);
    }
}

 通常遍历元素的话有三种方式,我都会写在下方的代码中:


import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class ArrayListDemo1 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("a");
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");


        /*
        遍历的方法
         */


        /*
        1.for循环 遍历
        可以区间遍历
         */
        /*for (int i = 0;i<arrayList.size();i++){
            //System.out.println(arrayList.get(i));   //直接遍历

            //删除元素
            if (arrayList.get(i).equals("a")){
                arrayList.remove(i);
                i--;//如果直接继续循环那遇到重复出现要删除的元素就不能完全删除
                //但是如此需要对索引掌握到位,不然就会出现错误
            }
        }*/



        /*
        2.增强for循环 遍历
        方便,但是只能全部遍历
         */
      /*  for(String s : arrayList) {
            System.out.println(s);
            //上方是遍历   

       */

       /*  
             //下方是删除元素
             if (s.equals("a")){
                arrayList.remove(s);
            }
            //无法通过该方式进行遍历修改元素,程序抛出异常
            *//*

        }*/

        /*
        3.迭代器遍历

         */
/*        Iterator<String> iterator = arrayList.iterator();
        while (iterator.hasNext()){
            String s = iterator.next();
            //System.out.println(s);
            if (s.equals("a")) {
                //此处不能使用list.remove(s);   因为一直在迭代器中操作,不能直接对arraylist操作
                iterator.remove();
            }
        }*/


/*        ListIterator<String> iterator1 = arrayList.listIterator();
        while (iterator1.hasNext()){
            String s = iterator1.next();
            if (s.equals("a")) {
                iterator1.remove();
            }
        }*/
        ListIterator<String> iterator1 = arrayList.listIterator(arrayList.size());
        while (iterator1.hasPrevious()){
            String s = iterator1.previous();
            if (s.equals("a")) {
                iterator1.remove();
            }
            System.out.println(s);
        }
        System.out.println(arrayList);
    }
}

LinkedList 存储方式为链表,可重复,按添加顺序排列

特点是查询比较慢(需要从头节点或者尾节点开始逐个查询)

但是增加或者删除元素比较方便

【具体解释请参照数据结构相关知识】

LinkedList与ArrayList用法差不多,需要注意的是LinkedList底层实现是链表,所以虽然方法名相同,但是底层实现代码不同



import java.util.LinkedList;

public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("a");
        linkedList.add("b");
        linkedList.add("c");
        linkedList.add("d");
        linkedList.add("e");
        linkedList.add("f");
        linkedList.add("g");
        linkedList.remove();//检索并删除此列表第一位
        linkedList.removeLast();//删除最后一位
        linkedList.size();
        linkedList.get(3);

        System.out.println(linkedList);

    }
}

Vector 线程安全,存储方式也是数组,一般用于多线程



import java.util.Vector;

public class VectorDemo {
    /*
    线程安全,底层也是数组实现
    synchronized 同步锁
     */
    public static void main(String[] args) {
        Vector<String> vector = new Vector<>();
        vector.add("a");
        vector.add("b");
        vector.add("c");
        vector.add("d");
        vector.add("e");
        vector.add("f");
        System.out.println(vector.size());
        vector.set(4, "z");
        System.out.println(vector.contains("c"));
        vector.remove("b");
        System.out.println(vector);

    }
}

Set:无序,不可重复

HashSet:元素不能重复,

Set接口实现类的共同特征:不能存储重复元素
HashSet:无序的(值的哈希码%数组长度【取余】)
TreeSet:有序的(排序)
//注意,下方有三部分代码,如果要复制,需要单独分开



import java.util.HashSet;

public class HashSetDemo1 {

    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("a");
        hashSet.add("x");
        hashSet.add("y");
        hashSet.add("d");
        hashSet.add("e");
        System.out.println(hashSet);
     
    }
}




import java.util.HashSet;

public class HashSetDemo2 {
    /*

    HashSet/HasMap中如何保证值(键)不重复:
    当添加一个元素时,首先会调用值的hashCode方法,计算出一个hash值
    但是!哈希值不安全,有可能内容不同,但是hash值相同,所以还要调用equals()方法,比较内容一致与否

    如果不先调用hashCode方法,那只调用equals方法会造成比较的效率低下,所以先调用hashCode方法
     */
    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("a");
        hashSet.add(new String("入地"));//哈希值一样,那就会开始调用equals()方法比较内容
        hashSet.add(new String("上天"));//哪怕new一个新对象,hashSet方法中也默认重写了equals()方法和hashCode()方法,不比较地址
        hashSet.add("d");
        hashSet.add("e");
        System.out.println(hashSet);
    }
}




import java.util.HashSet;

public class HashSetDemo3 {
    
    public static void main(String[] args) {
        HashSet<Car> hashSet = new HashSet<>();
        Car car1 = new Car(101, "奔驰1");
        Car car2 = new Car(101, "奔驰1");
        Car car3 = new Car(103, "奔驰3");
        Car car4 = new Car(104, "奔驰4");
        Car car5 = new Car(105, "奔驰5");
        hashSet.add(car1);
        hashSet.add(car2);
        hashSet.add(car3);
        hashSet.add(car4);
        hashSet.add(car5);
        System.out.println(hashSet);
        //只有四个元素,因为Car类中重写了equals()   hashCode()方法,先用哈希值比较,若相同再使用euqals()方法比较,
        //若没有重写,那根据Object中hashCode()方法,使用他们的地址比较,这是两个对象,必然有两个不同的地址,此时会有5个元素
    }
}


//上下两处都要用到自定义的Car类



public class Car implements Comparable<Car>{
    private int num;
    private String name;

    public Car(int num, String name) {
        this.num = num;
        this.name = name;
    }

    @Override
    //必须定义类时重写hashCode()方法,不然默认调用父类Object中的hashCode方法,比较的是地址,而不是内容
    public int hashCode() {
        int result = num;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
    @Override
    public String toString() {
        return "Car{" +
                "num=" + num +
                ", name='" + name + '\'' +
                '}';
    }

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

        Car car = (Car) o;

        if (num != car.num) return false;
        return name != null ? name.equals(car.name) : car.name == null;
    }


    @Override
    //TreeSet中比较的方法   需要有参考的参数
    public int compareTo(Car o) {
        return this.num-o.num;
    }
}

TreeSet:元素不能重复,但是是有序的(由排序得来)

import java.util.TreeSet;

public class TreeSetDemo1 {
    /*
    TreeSet   不可重复,有序的(可以排序)
     */
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>();
        set.add("a");
        set.add("d");
        set.add("f");
        set.add("e");
        set.add("c");
        System.out.println(set);
    }
}
import java.util.TreeSet;

public class TreeSetDemo2 {
    /*
    TreeSet   不可重复,有序的(可以排序)
     */
    public static void main(String[] args) {
        TreeSet<Car> set = new TreeSet<>();
        Car car1 = new Car(101, "奔驰1");
        Car car2 = new Car(101, "奔驰1");
        Car car3 = new Car(103, "奔驰3");
        Car car4 = new Car(104, "奔驰4");
        Car car5 = new Car(105, "奔驰5");
        set.add(car1);
        set.add(car3);
        set.add(car5);
        set.add(car4);
        set.add(car2);
        System.out.println(set);
    }
}

Set遍历只能用增强for循环和iterator(迭代器)。

因为Set里没有索引,所以不能用for循环 

Map:(双列)

HashMap:使用哈希表

HashTable:

TreeMap:使用树结构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值