法--傻瓜笔记--1123(第七章:集合/容器)

法–傻瓜笔记–1123(第七章:集合/容器)

袁永豪 2020-11-25 21:35:26 41 收藏 2
分类专栏: 笔记 文章标签: java
版权
第七章:集合/容器
集合:能动态增长长度,并且可以实现各种数据结构的容器,就是集合。
Java的集合框架是由很多接口、抽象类、具体类组成的,都位于java.util包中

1.Collection接口
数组的缺点: 长度一旦定义就不可变 , 结构单一 ,只存储类型相同的元素
Collection(集合接口):不能实例化 集合可以存储引用类型(默认是Object类型),可以添加任何元素,它会先用valueOf()自动装箱,最好还是向集合中添加同一类型的元素

1.基本方法
public static void main(String[] args) {
// 通过子类创建父类对象
Collection c = new ArrayList();

    // 向末尾添加元素
    c.add(2);
    c.add("3");
    c.add(4);
    c.add(3);
    c.add("6");
    c.add(true);// 它会先用valueOf()自动装箱
    System.out.println(c);

    // 删除指定元素,并且删除时需要与输入时的数据类型相同
    c.remove("3");
    System.out.println(c);

    // size()方法 得到集合的长度
    // length属性 得到数组的长度
    // length()方法 得到字符串的长度
    System.out.println(c.size());

    // isEmpty 是否为空
    System.out.println(c.isEmpty());

    // contains 是否包含
    System.out.println(c.contains(3));

    // clear 清空

// c.clear();
// System.out.println©;

    // addAll 将一个集合添加到另一个集合中
    Collection c1 = new ArrayList();
    c1.add(7);
    c1.add(8);
    c1.add(9);
    c1.addAll(c);
    System.out.println(c1);

    // containsAll 集合 c1 是否包含集合 c
    System.out.println(c1.containsAll(c));

    // removeAll 删除集合c1中与c相同的元素

// c1.removeAll©;
// System.out.println(c1);

    // retainAll c1中只保留c1与c的交集,有改变时返回true
    System.out.println(c1.retainAll(c));
    System.out.println(c1);

    // removeIf有选择地删除指定元素  匿名内部类过滤
    System.out.println(c1.removeIf(new Predicate() {
        @Override
        public boolean test(Object o) {
            return o.equals("6");
        }
    }));
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
2.集合转数组 toArray( )
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(“1”);
c.add(“2”);
c.add(“3”);
c.add(“4”);

    // 第一种方式
    Object obj = c.toArray();
    System.out.println(obj.toString());

    // 第二种方式
    Collection<String> c1 = new ArrayList<String>();// JDK8以后如果前面写了,后面就不用写了。
    c1.add("5");
    c1.add("6");
    c1.add("7");
    c1.add("8");

    String[] s = c1.toArray(new String[c1.size()]);
    System.out.println(Arrays.toString(s));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
3.数组转集合 asList(T… a)
public static void main(String[] args) {
// asList(T…a)数组转换列表
Integer[] i = new Integer[]{1,2,4};
List list = Arrays.asList(i);
System.out.println(list);

    // 可变长度参数,可同时传入多个参数
    // 本质是一个数组,一个参数列表只能有一个
    // 必须方法参数列表末尾,可以直接传一个数组。
    test(1,2,3,4);
}

public static void test(int...a){
    System.out.println("");
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
4.特殊方法 sort( ),subList( ),removeRange( )
public static void main(String[] args) {
ArrayList a = new ArrayList();
a.add(“s”);
a.add(“d”);
a.add(“f”);
a.add(“a”);
a.add(“t”);
a.add(“k”);

    // 不能直接使用sort函数,需要创建一个比较类
    a.sort(new StringC());
    System.out.println(a);

    // 从集合中截取元素,包括开始,不包括结束
    System.out.println(a.subList(2,5));

    // 删除指定区间元素  包含开始,不包含结束
    CollectionDemo3 list = new CollectionDemo3();
    list.add("s");
    list.add("d");
    list.add("f");
    list.add("a");
    list.add("t");
    list.add("k");

    list.removeRange(0,3);
    System.out.println(list);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
排序所需要的比较类
public class StringC implements Comparator {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
}
1
2
3
4
5
6
2.List接口
List:数据对象 有顺序 且 可以重复。
List继承了Collection接口,有三个实现的类,分别是下面的三个:
LinkedList:采用双向链表存储方式。插入、删除元素时效率比较高
Vector: 数组列表,同步锁,线程安全的,两倍扩容
ArrayList: 数组列表,数据采用数组方式存储,实现了长度可变的数组,一点五倍扩容。遍历元素与随机访问元素效率高。

1.ArrayList
ArrayList: 数组列表,数据采用数组方式存储,实现了长度可变的数组,一点五倍扩容。
在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高。(是我们最常用的)

public static void main(String[] args) {
    // ArrayList的默认空间初始值是10,如果需要更大的空间,建议在一开始初始化的时候就设置新的空间大小。
    // ArrayList的常用方法
    ArrayList a1 = new ArrayList(100);
    a1.add(0,1);
    a1.add(1,3);
    a1.add(0,2);
    a1.add(1,4);
    a1.add(3,4);
    a1.add(3,2);
    a1.add(9);// 不加索引就是向末尾插入
    System.out.println(a1);// [2, 4, 1, 3]
    // 测试之前add()方法是赋值的意思,结果出来之后知道了,是以插入的方法进行赋值

    // get()方法是通过指定index索引得到数组元素
    System.out.println(a1.get(0));// 4

    // indexOf方法是 从头遍历寻找指定元素的索引值
    // 如果搜索的是数组中没有的值,那么会返回 -1
    // 如果有重复的元素,会返回距离头部最近的元素的索引
    System.out.println(a1.indexOf(4));

    // lastIndexOf 从尾遍历寻找指定元素的索引值
    // 如果搜索的是数组中没有的值,那么会返回 -1
    // 如果有重复的元素,会返回距离尾部最近的元素的索引
    System.out.println(a1.lastIndexOf(2));

    // remove 删除并返回指定位置的元素
    // 如果超过索引范围,就会抛出异常java.lang.IndexOutOfBoundsException
    System.out.println(a1.remove(2));
    System.out.println(a1);// [2, 4, 2, 4, 3]

    // set 修改指定索引的元素值
    // 如果超过索引范围,就会抛出异常java.lang.IndexOutOfBoundsException
    a1.set(3,9);
    System.out.println(a1);// [2, 4, 2, 9, 3]
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2.LinkedList
LinkedList:采用双向链表存储方式。插入、删除元素时效率比较高

public static void main(String[] args) {
LinkedList a = new LinkedList();

    // add 向指定索引处插入元素
    a.add(0,1);
    a.add(1,2);
    a.add(2,3);
    a.add(1,4);
    a.add(4,5);
    System.out.println(a);// [1, 4, 2, 3, 5]

    // addFirst  向头部插入指定元素
    a.addFirst(3);
    a.addFirst(0);
    System.out.println(a);// [0, 3, 1, 4, 2, 3, 5]

    // addLast  向尾部插入指定元素
    a.addLast(9);
    a.addLast(10);
    System.out.println(a);// [0, 3, 1, 4, 2, 3, 5, 9, 10]

    // remove 删除指定索引的元素
    // 超出索引位置会报错java.lang.IndexOutOfBoundsException
    a.remove(7);
    System.out.println(a);// [0, 3, 1, 4, 2, 3, 5, 10]

    // removeFirt  删除头部首个元素
    a.removeFirst();
    System.out.println(a);// [3, 1, 4, 2, 3, 5, 10]

    // removeLast  删除尾部首个元素
    a.removeLast();
    System.out.println(a);// [3, 1, 4, 2, 3, 5]

    // getFirst  获得头部的首个元素
    System.out.println(a.getFirst());// 3

    // getLast 获得尾部的首个元素
    System.out.println(a.getLast());// 5

    // 因为LinkedList 和 ArrayList实现了同一个接口List所以能调用的方法基本是一样的
    System.out.println(a.get(2));// 4
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
3.Vector
vector: 底层也是数组实现的,可扩容,,多线程安全。(方法基本与ArrayList一样)

Vector v = new Vector<>();
v.add(“1”);
v.add(“3”);
v.add(“2”);
v.add(“2”);
v.add(“4”);
System.out.println(v);//[1, 3, 2, 2, 4]
1
2
3
4
5
6
7
4.集合遍历
集合遍历:

for循环
foreach循环
iterator迭代器
public static void main(String[] args) {
Vector v = new Vector<>();
v.add(“1”);
v.add(“3”);
v.add(“2”);
v.add(“2”);
v.add(“4”);
System.out.println(v);//[1, 3, 2, 2, 4]

    // 集合迭代与遍历
    // for循环遍历
    for (int i = 0; i < v.size(); i++) {
        System.out.print(v.get(i));// 1324
        if(v.get(i).equals("2")){
            v.remove(i);
            /*
            * 删除元素后,长度减一,元素向前移动一位。
            * 想解决这个问题,可以在执行完删除操作后,i--
            * */
            i--;
        }
    }
    System.out.println();
    System.out.println(v);// [1, 3, 4]

    // foreach 遍历
    for(String vector : v){
        System.out.print(vector);// 遍历
        if(vector.equals("3")){
            v.remove(vector);
            break;
            /*
            * 如果删除元素就会抛出异常,即不允许在遍历过程中进行操作。
            * ConcurrentModificationException  表明不能修改
            * 如果必要进行删除,可以在删除元素后立即退出循环,这样就不会抛出异常。
            * */
        }
    }
    System.out.println();
    System.out.println(v);// [1, 4]

    // 迭代器 Iterator ——> 接口
    Iterator<String> iterator = v.iterator();
    while(iterator.hasNext()){// 是否还有元素
        String s = iterator.next();
        System.out.println(s);// 遍历
        iterator.remove();// 拿一个删除一个
                        // 必须使用Iterator专用删除方法,无需参数,不然也会抛出异常
        // 删除指定元素

// if(iterator.equals(“1”)){
// iterator.remove();
// }
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
3.泛型
泛型:早期的Object类可以表示接收任何类型,但是在类型转换时,存在一定的隐患,因此出现了泛型
泛型类型可以添加任何元素,但只能是引用类型,例:Integer
泛型类型默认是 Object类型
泛型可以有多个,例如 在类声明时

/*

  • 泛型:早期的Object类可以表示接收任何类型,但是在类型转换时,存在一定的隐患,因此出现了泛型

  •  泛型类型可以添加任何元素,但只能是引用类型,例:Integer
    
  •  泛型类型默认是 Object类型
    
  •  泛型可以有多个,例如 在类声明时
    
  • */
    public class GenericDemo {
    // 泛型在类声明中使用,可以是多个,例:<T,V,K>
    Object obj;

    public static void main(String[] args) {
    // 向上转型,没问题,但是向下转型可能会有问题
    GenericDemo generic = new GenericDemo();
    generic.obj = 1;
    generic.obj = “1”;
    generic.obj = true;

     ArrayList arr = new ArrayList();
     arr.add(1);
     arr.add("2");
     arr.add(true);
    
     for (int i = 0; i < arr.size(); i++) {
         Object obj = arr.get(i);// 这样是没问题的
         System.out.print(obj);// 1, 2, true
     }
     System.out.println();
    
     for (int i = 0; i < arr.size(); i++) {
         // String s = arr.get(i);
         /*
          * 这样会直接编译报错,
          * 因为String类与Integer类和Boolean类都是Object类的子类,
          * 但是他们之间没有关联,是"平级的"
          * 因此会编译失败
          * */
         // 这种时候还想要遍历的话就需要加一个判断
         // 但是当一个集合中的数据类型过多的时候,这就会很麻烦
         Object obj = arr.get(i);
         if (obj instanceof String) {
             String s1 = (String) obj;
             System.out.println(s1);
         }
     }
    
     // 如果使用泛型的话就会直接确定集合元素的类型
     ArrayList<String> alist = new ArrayList<String>();
     // JDK-8 以后可以不用再写后面的类型
     // 类型不对的话,会在添加元素编译的时候直接报错
     // alist.add(1);
     // alist.add(true);
     alist.add("1");
     alist.add("2");
     alist.add("3");
     for (int i = 0; i < alist.size(); i++) {
         System.out.print(alist.get(i));
     }
    

    }

    // 泛型在方法中使用
    public T test(T t1) {
    return t1;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    4.Set接口
    Set:接口,不允许重复元素

HashSet:无序(不是按照添加顺序排序,而是按照哈希值排序),不可重复

TreeSet:有序(按照元素的自然顺序存储,例如2,1,3——> 1,2,3)不可重复。数据类型必须 实现comparable接口 , 重写compareTo()

1.HashSet
hashSet:无序(不是按照添加顺序排序,而是按照哈希值排序),不可重复
哈希表加链表存储,同一位置可以存储不同内容的元素
底层为hashMap
public native hashcode(),native 意为调用本地系统方法

public static void main(String[] args) {
Student s1 = new Student(1,“jim1”);
Student s2 = new Student(2,“jim1”);
Student s3 = new Student(3,“jim1”);
Student s4 = new Student(4,“jim4”);

    // 添加时根据内容的hash值,再经过hash函数计算得到元素在hash表中存储的位置
    HashSet hashSet = new HashSet();
    hashSet.add(s1);
    hashSet.add(s2);
    hashSet.add(s3);
    hashSet.add(s4);
    // 如果不在student类中重写hashcode(),那么就会调用Object中hashcode()方法算出对象(对象不同,哈希值就不同)的哈希值

    // 重写Object类中hashCode(),来自己根据对象中包含的内容计算hash值。
    // 向hashSet中添加元素是如何判断重复元素?
    // 底层是双保险,既要提高判断效率,又要安全可靠。
    /*
    * ① 首先通过hashcode()算出添加内容的哈希值,判断hash值在集合中是否存在,
    * 但是有时哈希值可能相同,但内容不同,因此并不安全
    * 效率高,但是可能会出现重复
    * ② 当哈希值相同时,就需要通过equals()足逐个判断元素内容是否相同。
    * 效率底,安全
    * */
    System.out.println(hashSet);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Student类
public class Student {
private int num;
private String name;

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

public Student() {
}

public int getNum() {
    return num;
}

public void setNum(int num) {
    this.num = num;
}

public String getName() {
    return name;
}

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

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    Student student = (Student) o;
    return num == student.num &&
            Objects.equals(name, student.name);
}

@Override
public int hashCode() {
    return Objects.hash(num,name);
}

@Override
public String toString() {
    return "Student{" +
            "num=" + num +
            ", name='" + name + '\'' +
            '}';
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
2.TreeSet
TreeSet:有序(按照元素的自然顺序存储,例如2,1,3——> 1,2,3)不可重复
数据类型必须 实现comparable接口 , 重写compareTo( )
底层为红黑树

public static void main(String[] args) {
TreeSet tset = new TreeSet();
tset.add(“c”);
tset.add(“d”);
tset.add(“b”);
tset.add(“a”);

    System.out.println(tset);//[a, b, c, d] 有序,按照内容的自然顺序排序

    // 自定义对象
    Student s1 = new Student(1,"stu1");
    Student s2 = new Student(2,"stu2");
    Student s3 = new Student(3,"stu3");
    Student s4 = new Student(4,"stu1");
    TreeSet<Student> ts = new TreeSet<Student>();

    ts.add(s1);
    ts.add(s2);
    ts.add(s3);
    ts.add(s4);

    // 自己定义的数据类型如果不实现comparable接口,并重写compareTo(),就会报错
    //          java.lang.ClassCastException
    System.out.println(ts);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值