day16

本文介绍了数据结构中的栈、队列、数组和链表,重点讲解了ArrayList和LinkedList的区别及使用场景。ArrayList基于数组实现,适合查询,不适合频繁增删;LinkedList基于链表,适合增删,不适合查询。此外,文章还详细阐述了Java中的泛型概念,包括其使用、好处、类型推断以及泛型类和方法。最后讨论了Set接口,展示了Set的创建和遍历方式。
摘要由CSDN通过智能技术生成

day16

一、数据结构

数据结构:实际上就是存储数据和展示数据的方式。合理的选择数据结构解决问题,可以获得比之前更高的运行效率。

常见的数据结构有:栈和队列、数组和链表

1.1 栈和队列

栈,stack。是一个受限的线性表。这个受限体现在存储和删除数据的时候都只能在一端操作。其它任何位置都不能进行存储和删除等操作。

特点:
1. 只能在一端进行访问(也就是出口和入口是一个位置)
2. 先进后出
栈
队列

队列,Queue。是一种受限的线性表。这个受限体现在只能在一端进入,在另一端出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yeX3wVOt-1620344821401)(img/image-20210426101844694.png)]

1.2 数组和链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Uq1KE2w-1620344821403)(img/image-20210426104419466.png)]

二、List的常见子类

ArrayList
LinkedList
2.1 ArrayList

底层是数组:查找快、增删慢

可以存储null值

不同步(不加锁),效率高

构造方法
ArrayList() 		构造一个初始容量为 10 的空列表
扩容方式【记住结论】
ArrayList的容量一旦不够用了,就会进行扩容。扩容的大小为原来数组的1.5倍。
int newCapacity = oldCapacity + (oldCapacity >> 1);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NknjjnfO-1620344821405)(img/image-20210426140539044.png)]

练习:
	1. 创建一个ArrayList集合,存储3个字符串,并通过迭代器遍历
	2. 创建一个ArrayList集合,存储3个Person对象,并通过迭代器遍历
使用集合的步骤 【掌握】
1. 创建集合对象
2. 创建元素对象
3. 将元素对象添加到集合对象中
4. 通过迭代器遍历
		1. 通过集合对象调用iterator方法获取迭代器对象
		2. 通过迭代器对象调用hasNext方法判断是否还有元素可以被迭代
		3. 通过迭代器对象调用next方法获取元素
public class Demo6 {

    public static void main(String[] args) {

        //1. 创建集合对象
        ArrayList al = new ArrayList();

        //2. 创建元素对象
        Person p = new Person("zhangsan", 33);
        Person p2 = new Person("lisi", 44);
        Person p3 = new Person("wangwu", 55);

        //3. 将元素对象添加到集合对象中
        al.add(p);
        al.add(p2);
        al.add(p3);

        //4. 通过迭代器遍历
        //4.1 通过集合对象调用iterator方法获取迭代器对象
        Iterator it = al.iterator();
        //4.2 通过迭代器对象调用hasNext方法判断是否还有元素可以被迭代
        while(it.hasNext()){

            //4.3 通过迭代器对象调用next方法获取元素
            Person next = (Person) it.next();
            System.out.println(next);
        }

    }
}
2.2 LinkedList

底层是链表:查找慢、增删快

可以存储null值

不同步(不加锁),效率高

构造方法
LinkedList() 		 构造一个空列表
public class Demo {

    public static void main(String[] args) {

        //LinkedList()      构造一个空列表
        LinkedList ll = new LinkedList();

        ll.add("A");
        ll.add("B");
        ll.add("C");

        Iterator it = ll.iterator();
        while(it.hasNext()){

            String next = (String) it.next();
            System.out.println(next);
        }

    }
}
特有方法
void addFirst(E e) 		将指定元素插入此列表的开头 
void addLast(E e) 		将指定元素添加到此列表的结尾 

E getFirst() 			返回此列表的第一个元素 
E getLast() 			返回此列表的最后一个元素 

E removeFirst() 		移除并返回此列表的第一个元素 
E removeLast() 			移除并返回此列表的最后一个元素 
public class Demo2 {

    public static void main(String[] args) {

        LinkedList ll = new LinkedList();

        ll.add("Hello");
        ll.add("World");
        ll.add("Java");

        System.out.println(ll);     //[Hello, World, Java]
        //void addFirst(E e) 		将指定元素插入此列表的开头
//        ll.addFirst("Japan");
//        System.out.println(ll);     //[Japan, Hello, World, Java]
//        ll.addFirst("England");
//        System.out.println(ll);     //[England, Japan, Hello, World, Java]

        //void addLast(E e) 		将指定元素添加到此列表的结尾
//        ll.addLast("Japan");
//        System.out.println(ll);       //[Hello, World, Java, Japan]

        //E getFirst() 			返回此列表的第一个元素
//        System.out.println(ll.getFirst());      //Hello

        //E getLast() 			返回此列表的最后一个元素
//        System.out.println(ll.getLast());         //Java

        //E removeFirst() 		移除并返回此列表的第一个元素
//        Object o = ll.removeFirst();
//        System.out.println("被移除的元素为:" + o);
//        System.out.println(ll);

        //E removeLast() 			移除并返回此列表的最后一个元素
        Object o = ll.removeLast();
        System.out.println("被移除的元素为:" + o);    // 被移除的元素为:Java
        System.out.println(ll);					    // [Hello, World]

    }
}
源码分析 【理解】
参考另一个笔记 【LinkedList源码分析.pdf】
2.3 如何选择List的子类
如果查询比较多,那么就使用 ArrayList
如果增删比较多,那么就使用 LinkedList

三、泛型 【会用】

泛型:就是一种参数化的类型。比如定义一个类的时候,类中的方法的参数或者返回值我们还不确定。那我们可以先用一个符号代替。这个符号就是泛型。

具体这个泛型(也就是符号)代替什么类型,那必须要等到我们使用的时候才能明确。

3.1 简单使用
不使用泛型
import java.util.ArrayList;
import java.util.Iterator;

public class Demo {

    public static void main(String[] args) {

        //不使用泛型
        ArrayList al = new ArrayList();

        al.add("Hello");
        al.add(666);
        al.add('中');

        Iterator it = al.iterator();
        while(it.hasNext()){

            String s = (String)it.next();   //类型转换异常
            System.out.println(s);
        }

    }
}
使用泛型 【掌握】
import java.util.ArrayList;
import java.util.Iterator;

public class Demo {

    public static void main(String[] args) {

        //使用泛型
        ArrayList<String> list = new ArrayList<String>();

        list.add("Hello");
//        list.add(666);   //编译报错
//        list.add('中');  //编译报错
        list.add("666");
        list.add("中");

        Iterator<String> itt = list.iterator();
        while(itt.hasNext()){

            String next = itt.next();
            System.out.println(next);
        }

    }
}
3.2 好处
1. 能将运行时期的问题,提前到了编译期
2. 省去了类型强转的麻烦
3.3 泛型的推断
如果已经通过数据类型确定好泛型之后,那么后面的<>中就可以不用再放具体的数据类型了(也就是留空即可)  jdk1.7出来的内容
public class Demo2 {

    public static void main(String[] args) {

        ArrayList<String> al = new ArrayList<>();

        al.add("Hello");
        al.add("Hello2");
        al.add("Hello3");

        Iterator<String> it = al.iterator();
        while(it.hasNext()){

            String s = it.next();
            System.out.println(s);
        }

    }
}
3.4 泛型类
格式:

class 类名 <泛型1, 泛型2, ...> {

}

注意:
    1. 泛型必须为引用数据类型
    2. 一个类可以同时在<>中声明多个泛型,中间用英文状态的逗号分隔开就行
    3. 泛型命名的时候只要符合标识符的命名规范即可,一般都用如下字母: K V T E
    4. 泛型只是一种参数化的类型,一旦在类上声明之后,就可以当成确定的类型在类中使用了。
public class DynamicArray <E> {

    private Object[] arr;
    private int size;
    
    public DynamicArray(){

        arr = new Object[10];
    }

    //添加方法
    public void add(E e){

        arr[size++] = e;
    }

}

public class Demo3 {

    public static void main(String[] args) {

//        DynamicArray<String> da = new DynamicArray<>();
//        da.add("Hello");

        DynamicArray<Integer> da = new DynamicArray<>();
        da.add(666);

    }
}
3.5 泛型方法
格式:

修饰符 <泛型1, 泛型2, ...> 返回值类型 方法名(参数列表) {

}

注意:
	1. 泛型方法中定义的泛型只能在本方法中使用,其它方法不能使用
public class DD {

    public <坤坤> void test(坤坤 kk){

        System.out.println("Hello:" + kk);
    }

}

public class Demo4 {

    public static void main(String[] args) {

        DD d = new DD();

        d.<String>test("Java");
        d.<Integer>test(666);

    }
}
3.6 泛型的通配符

如果你不知道要使用什么泛型,那么就直接使用?即可。 ?就代表了所有的泛型

?				代表了所有的泛型
? extends E		代表了E类型,及其E类型所有的子类
? super E		代表了E类型,及其E类型所有的父类
package com.ujiuye.demo03_泛型;

import java.util.ArrayList;

class Animal { }
class Dog extends Animal {}
class Cat extends Animal {}
class CoffeeCat extends Cat {}

public class Demo5 {

    public static void main(String[] args) {

        //?				    代表了所有的泛型
//        ArrayList<?> al = new ArrayList<Animal>();
//        ArrayList<?> al2 = new ArrayList<Dog>();
//        ArrayList<?> al3 = new ArrayList<Cat>();
//        ArrayList<?> al4 = new ArrayList<CoffeeCat>();

        //? extends E		代表了E类型,及其E类型所有的子类
//        ArrayList<? extends Cat> al = new ArrayList<Animal>();      //编译报错
//        ArrayList<? extends Cat> al2 = new ArrayList<Dog>();        //编译报错
//        ArrayList<? extends Cat> al3 = new ArrayList<Cat>();
//        ArrayList<? extends Cat> al4 = new ArrayList<CoffeeCat>();

        //? super E		    代表了E类型,及其E类型所有的父类
//        ArrayList<? super Cat> al = new ArrayList<Animal>();
//        ArrayList<? super Cat> al2 = new ArrayList<Dog>();          //编译报错
//        ArrayList<? super Cat> al3 = new ArrayList<Cat>();
//        ArrayList<? super Cat> al4 = new ArrayList<CoffeeCat>();    //编译报错

    }
}

四、Set

一个不包含重复元素的 collection。

Set不保证元素的有序性。

没有索引

4.1 获取Set对象的方式
通过其实现类创建对象

Set<String> set = new HashSet<>();
import java.util.HashSet;
import java.util.Set;

public class Demo {

    public static void main(String[] args) {

        //1. 创建Set集合的对象
        Set<String> set = new HashSet<>();

        //2. 将元素对象添加到集合中
        set.add("hello");
        set.add("java");
        set.add("world");
        set.add("java");

        //3. 输出
        System.out.println(set);        //[java, world, hello]   无序
        System.out.println("-------------------");

        Set<Character> set2 = new HashSet<>();
        set2.add('A');
        set2.add('Z');
        set2.add('C');

        System.out.println(set2);      //[A, C, Z]   有序

    }
}
4.2 遍历Set的方式
1. toArray
2. toArray(T[] a) 
3. iterator
4. 增强for
package com.ujiuye.demo04_Set接口;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Demo2 {

    public static void main(String[] args) {

        Set<String> set = new HashSet<>();
        set.add("hello");
        set.add("world");
        set.add("java");

        //1. toArray
//        Object[] objects = set.toArray();
//        for(int i = 0; i < objects.length; i++){
//
//            System.out.println(objects[i]);
//        }

        //2. toArray(T[] a)
        //先按照结果的类型创建一个数组,用来存储结果
//        String[] s = new String[set.size()];
//        String[] ss = set.toArray(s);
//        for(int i = 0; i < ss.length; i++){
//
//            System.out.println(ss[i]);
//        }

        //3. iterator
        //while中使用iterator  【目前建议使用】
//        Iterator<String> it = set.iterator();
//        while(it.hasNext()){
//            String next = it.next();
//            System.out.println(next);
//        }

        //for中使用iterator     【开发中建议使用】
//        for(Iterator<String> it = set.iterator(); it.hasNext();){
//
//            String next = it.next();
//            System.out.println(next);
//        }

        //4. 增强for
//        for(String s : set){
//
//            System.out.println(s);
//        }
        
        //输出集合
        System.out.println(set.toString());

    }
}

ng> it = set.iterator();
// while(it.hasNext()){
// String next = it.next();
// System.out.println(next);
// }

    //for中使用iterator     【开发中建议使用】

// for(Iterator it = set.iterator(); it.hasNext()😉{
//
// String next = it.next();
// System.out.println(next);
// }

    //4. 增强for

// for(String s : set){
//
// System.out.println(s);
// }

    //输出集合
    System.out.println(set.toString());

}

}












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值