IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> JavaSE个人复习式整理知识点之基础语法十(List、Set、数据结构、Collections) -> 正文阅读

[数据结构与算法]JavaSE个人复习式整理知识点之基础语法十(List、Set、数据结构、Collections)

1 数据结构

1.2 常?的数据结构

数据存储的常?结构有:栈、队列、数组、链表和红?树。我们分别来了解?下:

  • 栈:stack,?称堆栈,它是运算受限的线性表,其限制是仅允许在标的?端进?插?和删除操作,不允许在其他任何位置进?添加、查找、删除等操作。

简单的说:采?该结构的集合,对元素的存取有如下的特点

  • 先进后出(即,存进去的元素,要在它后?存进去的元素依次取出后,才能取出该元素)。例如,?弹压进弹夹,先压进去的?弹在下?,后压进去的?弹在上?,当开枪时,先弹出上?的?弹,然后才能弹出下?的?弹。
  • 栈的??、出?的都是栈的顶端位置在这里插入图片描述
    这?两个名词需要注意:
  • 压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底?向移动?个位置。
  • 弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶?向移动?个位置。

队列

  • 队列:queue,简称队,它同堆栈?样,也是?种运算受限的线性表,其限制是仅允许在表的?端进?插?,?在表的另?端进?删除。

简单的说,采?该结构的集合,对元素的存取有如下的特点:

  • 先进先出(即,存进去的元素,要在后它前?的元素依次取出后,才能取出该元素)。例如,???过?洞,?头先进去,?尾后进去;?头先出来,?尾后出来。
  • 队列的??、出?各占?侧。例如,下图中的左侧为??,右侧为出?。
    在这里插入图片描述

数组

  • 数组:Array,是有序的元素序列,数组是在内存中开辟?段连续的空间,并在此空间存放元素。就像是?排出租屋,有100个房间,从001到100每个房间都有固定编号,通过编号就可以快速找到租房?的?。

简单的说,采?该结构的集合,对元素的存取有如下的特点:

  • 查找元素快:通过索引,可以快速访问指定位置的元素在这里插入图片描述
  • 增删元素慢
    • 指定索引位置增加元素:需要创建?个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置。如下图在这里插入图片描述

链表

  • 链表:linked list,由?系列结点node(链表中每?个元素称为结点)组成,结点可以在
    运?时动态?成。每个结点包括两个部分:?个是存储数据元素的数据域,另?个是存储下
    ?个结点地址的指针域。我们常说的链表结构有单向链表与双向链表,那么这?给?家介绍
    的是单向链表。在这里插入图片描述

简单的说,采?该结构的集合,对元素的存取有如下的特点:

  • 多个结点之间,通过地址进?连接。例如,多个??拉?,每个?使???的右?拉住下个?的左?,依次类推,这样多个?就连在?起了。在这里插入图片描述

  • 查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素

  • 增删元素快

    • 增加元素:只需要修改连接下个元素的地址即可。在这里插入图片描述
    • 删除元素:只需要修改连接下个元素的地址即可。在这里插入图片描述

红?树

  • ?叉树:binary tree ,是每个结点不超过2的有序树(tree),顶上的叫根结点,两边被称作“左?树”和“右?树”。

简单的理解,就是?种类似于我们?活中树的结构,只不过每个结点上都最多只能有两个?结点。

如图:在这里插入图片描述

我们要说的是?叉树的?种?较有意思的叫做红?树,红?树本身就是?棵?叉查找树,将节点插?后,该树仍然是?颗?叉查找树。也就意味着,树的键值仍然是有序的。
红?树的约束:

  1. 节点可以是红?的或者??的
  2. 根节点是??的
  3. 叶?节点(特指空节点)是??的
  4. 每个红?节点的?节点都是??的
  5. 任何?个节点到其每?个叶?节点的所有路径上??节点数相同

红?树的特点
速度特别快,趋近平衡树,查找叶?元素最少和最多次数不多于?倍

2 List集合

我们掌握了Collection接?的使?后,再来看看Collection接?中的?类,他们都具备那些特性呢?

接下来,我们?起学习Collection中的常??个?类( java.util.List 集合、 java.util.Set 集合)。

2.1 List接?介绍

java.util.List 接?继承? Collection 接?,是单列集合的?个重要分?,习惯性地会将实现了 List 接?的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以?种线性?式进?存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List集合还有?个特点就是元素有序,即元素的存?顺序和取出顺序?致

看完API,我们总结?下:

List接?特点

  1. 它是?个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。
  2. 它是?个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是?个道理)。
  3. 集合中可以有重复的元素,通过元素的equals?法,来?较是否为重复的元素。

Tips:我们在基础班的时候已经学习过List接?的?类java.util.ArrayList类,该类中的?法都是来?List中定义。

2.2 List接?中常??法

List作为Collection集合的?接?,不但继承了Collection接?中的全部?法,?且还增加了?些根据元素索引来操作集合的特有?法,如下:

  • public void add(int index, E element) :将指定的元素,添加到该集合中的指定位置上。
  • public E get(int index) :返回集合中指定位置的元素。
  • public E remove(int index) :移除列表中指定位置的元素, 返回的是被移除的元素。
  • public E set(int index, E element) :?指定元素替换集合中指定位置的元素,返回值的更新前的元素。

List集合特有的?法都是跟索引相关,我们在基础班都学习过,那么我们再来复习?遍吧:

public class ListDemo {
    public static void main(String[] args) {
        // 创建List集合对象
        List<String> list = new ArrayList<String>();
        // 往尾部添加 指定元素
        list.add("图图");
        list.add("?美");
        list.add("不?兴");
        System.out.println(list);
        // add(int index,String s) 往指定位置添加
        list.add(1, "没头脑");
        System.out.println(list);
        // String remove(int index) 删除指定位置元素 返回被删除元素
        // 删除索引位置为2的元素
        System.out.println("删除索引位置为2的元素");
        System.out.println(list.remove(2));
        System.out.println(list);
        // String set(int index,String s)
        // 在指定位置进?元素替代(改)
        // 修改指定位置元素
        list.set(0, "三?");
        System.out.println(list);
        // String get(int index) 获取指定位置元素
        // 跟size() ?法?起?来遍历的
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        //还可以使?增强for
        for (String string : list) {
            System.out.println(string);
        }
    }
}

3 List的?类

3.1 ArrayList集合

java.util.ArrayList 集合数据存储的结构是数组结构。元素增删慢,查找快,由于?常开发中使?最多的功能为查询数据、遍历数据,所以 ArrayList 是最常?的集合。

许多程序员开发时?常随意地使?ArrayList完成任何需求,并不严谨,这种?法是不提倡的。

3.2 LinkedList集合

java.util.LinkedList 集合数据存储的结构是链表结构。?便元素添加、删除的集合。

LinkedList是?个双向链表,那么双向链表是什么样?的呢,我们?个图了解下

在这里插入图片描述

实际开发中对?个集合元素的添加与删除经常涉及到?尾操作,?LinkedList提供了?量?尾操作的?法。这些?法我们作为了解即可:

  • public void addFirst(E e) :将指定元素插?此列表的开头。
  • public void addLast(E e) :将指定元素添加到此列表的结尾。
  • public E getFirst() :返回此列表的第?个元素。
  • public E getLast() :返回此列表的最后?个元素。
  • public E removeFirst() :移除并返回此列表的第?个元素。
  • public E removeLast() :移除并返回此列表的最后?个元素。
  • public E pop() :从此列表所表示的堆栈处弹出?个元素。
  • public void push(E e) :将元素推?此列表所表示的堆栈。
  • public boolean isEmpty() :如果列表不包含元素,则返回true。

LinkedList是List的?类,List中的?法LinkedList都是可以使?,这?就不做详细介绍,我们只需要了解LinkedList的特有?法即可。在开发时,LinkedList集合也可以作为堆栈,队列的结构使?。

?法演示:

public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList<String> link = new LinkedList<String>();
        // 添加元素
        link.addFirst("abc1");
        link.addFirst("abc2");
        link.addFirst("abc3");
        System.out.println(link);
        // 获取元素
        System.out.println(link.getFirst());
        System.out.println(link.getLast());
        // 删除元素
        System.out.println(link.removeFirst());
        System.out.println(link.removeLast());
        while (!link.isEmpty()) { // 判断集合是否为空
            System.out.println(link.pop()); // 弹出集合中的栈顶元素
        }
        System.out.println(link);
    }
}

4 Set接?

java.util.Set 接?和 java.util.List 接??样,同样继承? Collection 接?,它与 Collection 接?中的?法基本?致,并没有对 Collection 接?进?功能上的扩充,只是?Collection 接?更加严格了。与 List 接?不同的是, Set 接?中元素?序,并且都会以某种规则保证存?的元素不出现重复

Set 集合有多个?类,这?我们介绍其中的 java.util.HashSetjava.util.LinkedHashSet 这两个集合。

Tips:Set集合取出元素的?式可以采?:迭代器增强for

4.1 HashSet集合介绍

java.util.HashSet 是 Set 接?的?个实现类,它所存储的元素是不可重复的,并且元素都是?序的(即存取顺序不?致)。 java.util.HashSet 底层的实现其实是?个 java.util.HashMap ?持.

HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯?性的?式依赖于: hashCodeequals ?法。

我们先来使??下Set集合存储,看下现象,再进?原理的讲解:

public class HashSetDemo {
    public static void main(String[] args) {
        // 创建 Set集合
        HashSet<String> set = new HashSet<String>();
        // 添加元素
        set.add(new String("cba"));
        set.add("abc");
        set.add("bac");
        set.add("cba");
        // 遍历
        for (String name : set) {
            System.out.println(name);
        }
    }
}

输出结果如下,说明集合中不能存储重复元素:

cba
abc
bac

Tips:根据结果我们发现字符串"cba"只存储了?个,也就是说重复的元素set集合不存储。

4.2 HashSet集合存储数据的结构(哈希表)

什么是哈希表呢?

JDK1.8之前,哈希表底层采?数组+链表实现,即使?链表处理冲突,同?hash值的链表都存
储在?个链表?。但是当位于?个桶中的元素较多,即hash值相等的元素较多时,通过key值依
次查找的效率较低。?JDK1.8中,哈希表存储采?数组+链表+红?树实现,当链表?度超过阈值
(8)时,将链表转换为红?树,这样??减少了查找时间。

简单的来说,哈希表是由数组+链表+红?树(JDK1.8增加了红?树部分)实现的,如下图所示。
在这里插入图片描述

为了?便?家的理解我们结合?个存储流程图来说明?下:在这里插入图片描述
总??之,JDK1.8引?红?树?程度优化了HashMap的性能,那么对于我们来讲保证HashSet集合元素的唯?,其实就是根据对象的hashCode和equals?法来决定的。如果我们往集合中存放?定义的对象,那么保证其唯?,就必须复写hashCode和equals?法建?属于当前对象的?较?式

4.3 HashSet存储?定义类型元素

给HashSet中存放?定义类型元素时,需要重写对象中的hashCode和equals?法,建???的?较?式,才能保证HashSet集合中的对象唯?。

创建?定义Student类

public class Student {
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class HashSetDemo2 {
    public static void main(String[] args) {
        // 创建集合对象 该集合中存储Student类型对象
        HashSet<Student> stuSet = new HashSet<Student>();
        // 存储
        Student stu = new Student("于谦", 43);
        stuSet.add(stu);
        stuSet.add(new Student("郭德纲", 44));
        stuSet.add(new Student("于谦", 43));
        stuSet.add(new Student("郭麒麟", 23));
        stuSet.add(stu);
        for (Student stu2 : stuSet) {
            System.out.println(stu2);
        }
    }
}
运行结果:
Student{name='郭德纲', age=44}
Student{name='于谦', age=43}
Student{name='郭麒麟', age=23}

4.4 LinkedHashSet

我们知道HashSet保证元素唯?,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办?

在HashSet下?有?个?类 java.util.LinkedHashSet ,它是链表和哈希表组合的?个数据存储结构。

演示代码如下:

public class LinkedHashSetDemo {
    public static void main(String[] args) {
        Set<String> set = new LinkedHashSet<String>();
        set.add("bbb");
        set.add("aaa");
        set.add("abc");
        set.add("bbc");
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}
结果:
bbb
aaa
abc
bbc

4.5 可变参数

在JDK1.5之后,如果我们定义?个?法需要接受多个参数,并且多个参数类型?致,我们可以对其简化成如下格式:

	修饰符 返回值类型 ?法名(参数类型... 形参名) { }

其实这个书写完全等价与

	修饰符 返回值类型 ?法名(参数类型[] 形参名) { }

只是后?这种定义,在调?时必须传递数组,?前者可以直接传递数据即可。

JDK1.5以后。出现了简化操作。 ?在参数上,称之为可变参数。

同样是代表数组,但是在调?这个带有可变参数的?法时,不?创建数组(这就是简单之处),直接将数组中的元素作为实际参数进?传递,其实编译成的.class?件,将这些元素先封装到?个数组中,在进?传递。这些动作都在编译.class?件时,?动完成了。

代码演示:

public class ChangeArgs {
    public static void main(String[] args) {
        int[] arr = {1, 4, 62, 431, 2};
        int sum = getSum(arr);
        System.out.println(sum);
        // 6 7 2 12 2121
        // 求 这?个元素和 6 7 2 12 2121
        int sum2 = getSum(6, 7, 2, 12, 2121);
        System.out.println(sum2);
    }

    /*
    * 完成数组 所有元素的求和 原始写法
    public static int getSum(int[] arr) {
        int sum = 0;
        for (int a : arr) {
            sum += a;
        }
        return sum;
    }
    */
    // 可变参数写法
    public static int getSum(int... arr) {
        int sum = 0;
        for (int a : arr) {
            sum += a;
        }
        return sum;
    }
}

Tips:上述getSum?法在同?个类中,只能存在?个。因为会发?调?的不确定性
注意:如果在?法书写时,这个?法拥有多参数,参数中包含可变参数,可变参数?定要写在参数列表的末尾位置。

5 Collections

5.1 常?功能

java.utils.Collections 是集合?具类,?来对集合进?操作。部分?法如下:

  • public static < T > boolean addAll(Collection< T > c, T… elements) :往集合中添加?些元素。
  • public static void shuffle(List<?> list) :打乱集合顺序。
  • public static < T > void sort(List< T > list) :将集合中元素按照默认规则排序。
  • public static < T > void sort(List< T > list,Comparator<? super T> ) :将集合中元素按照指定规则排序。

代码演示:

public class CollectionsDemo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        // 原来写法
        // list.add(12);
        // list.add(14);
        // list.add(15);
        // list.add(1000);
        // 采??具类完成 往集合中添加元素
        Collections.addAll(list, 5, 222, 1, 2);
        System.out.println(list);
        // 排序?法
        Collections.sort(list);
        System.out.println(list);
    }
}
结果:
[5, 222, 1, 2] 
[1, 2, 5, 222]

代码演示之后 ,发现我们的集合按照顺序进?了排列,可是这样的顺序是采?默认的顺序,如果想要指定顺序那该怎么办呢?

我们发现还有个?法没有讲, public static < T > void sort(List< T > list,Comparator<? super T> ) :将集合中元素按照指定规则排序。接下来讲解?下指定规则的排列。

5.2 Comparator?较器

我们还是先研究这个?法
public static < T > void sort(List< T > list) :将集合中元素按照默认规则排序。
不过这次存储的是字符串类型。

public class CollectionsDemo2 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("cba");
        list.add("aba");
        list.add("sba");
        list.add("nba");
        // 排序?法
        Collections.sort(list);
        System.out.println(list);
    }
}

结果:

[aba, cba, nba, sba]

我们使?的是默认的规则完成字符串的排序,那么默认规则是怎么定义出来的呢?

说到排序了,简单的说就是两个对象之间?较??,那么在JAVA中提供了两种?较实现的?式,?种是?较死板的采? java.lang.Comparable 接?去实现,?种是灵活的当我需要做排序的时候在去选择的 java.util.Comparator 接?完成。

那么我们采?的 public static < T > void sort(List< T > list) 这个?法完成的排序,实际上要求了被排序的类型需要实现Comparable接?完成?较的功能,在String类型上如下:

public final class String implements java.io.Serializable,
Comparable<String>, CharSequence { }

String类实现了这个接?,并完成了?较规则的定义,但是这样就把这种规则写死了,那?如我想要字符串按照第?个字符降序排列,那么这样就要修改String的源代码,这是不可能的了,那么这个时候我们可以使?public static < T > void sort(List< T > list,Comparator<? super T> ) ?法灵活的完成,这个??就涉及到了Comparator这个接?,位于位于java.util包下,排序是comparator能实现的功能之?,该接?代表?个?较器,?较器具有可?性!顾名思义就是做排序的,通俗地讲需要?较两个对象谁排在前谁排在后,那么?较的?法就是:

  • public int compare(String o1, String o2) :?较其两个参数的顺序。

两个对象?较的结果有三种:?于,等于,?于。
如果要按照升序排序, 则o1 ?于o2,返回(负数),相等返回0,o1?于o2返回(正数)
如果要按照降序排序 则o1 ?于o2,返回(正数),相等返回0,o1?于o2返回(负数)

操作如下:

public class CollectionsDemo3 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        list.add("cba");
        list.add("aba");
        list.add("sba");
        list.add("nba");
        // 排序?法 按照第?个单词的降序
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o2.charAt(0) - o1.charAt(0);
            }
        });
        System.out.println(list);
    }
}
结果如下:
[sba, nba, cba, aba]

5.3 简述Comparable和Comparator两个接?的区别。

Comparable:强?对实现它的每个类的对象进?整体排序。这种排序被称为类的?然排序,类
compareTo ?法被称为它的?然?较?法。只能在类中实现 compareTo() ?次,不能经常修
改类的代码实现??想要的排序。实现此接?的对象列表(和数组)可以通过Collections.sort(和Arrays.sort) 进??动排序,对象可以?作有序映射中的键或有序集合中的元素,?需指定?较器。

Comparator:强?对某个对象进?整体排序。可以将 Comparator 传递给 sort ?法 (如Collections.sort或 Arrays.sort) ,从?允许在排序顺序上实现精确控制。还可以使?Comparator 来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有?然顺序的对象 collection 提供排序。

5.4 练习

创建?个学?类,存储到ArrayList集合中完成指定排序操作。
Student 初始类

public class Student {
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

测试类:

public class Demo {
    public static void main(String[] args) {
        // 创建四个学?对象 存储到集合中
        ArrayList<Student> list = new ArrayList<Student>();
        list.add(new Student("rose",18));
        list.add(new Student("jack",16));
        list.add(new Student("abc",16));
        list.add(new Student("ace",17));
        list.add(new Student("mark",16));
        /*
         *让学? 按照年龄排序 升序
         */
        // Collections.sort(list); // 要求:该list中元素类型 必须实现?较器
        Comparable接?
        for (Student student : list) {
            System.out.println(student);
        }
    }
}

发现,当我们调? Collections.sort() ?法的时候 程序报错了。

原因:如果想要集合中的元素完成排序,那么必须要实现?较器 Comparable 接?。

于是我们就完成了 Student 类的?个实现,如下:

public class Student implements Comparable<Student> {
 ....
    @Override
    public int compareTo(Student o) {
        return this.age - o.age; // 升序
    }
}

再次测试,代码就OK 了效果如下:

Student{name='jack', age=16}
Student{name='abc', age=16}
Student{name='mark', age=16}
Student{name='ace', age=17}
Student{name='rose', age=18}

5.5 扩展

如果在使?的时候,想要独?的定义规则去使? 可以采?Collections.sort(List list,Comparetor c)?式,??定义规则:

Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
        return o2.getAge()-o1.getAge();//以学?的年龄降序
    }
});
Student{name='rose', age=18}
Student{name='ace', age=17}
Student{name='jack', age=16}
Student{name='abc', age=16}
Student{name='mark', age=16}

如果想要规则更多?些,可以参考下?代码:

Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
		// 年龄降序
        int result = o2.getAge() - o1.getAge(); // 年龄降序
        if (result == 0) { // 第?个规则判断完了 下?个规则 姓名的?字? 升序
            result = o1.getName().charAt(0) - o2.getName().charAt(0);
        }
        return result;
    }
});

效果如下:

Student{name='rose', age=18}
Student{name='ace', age=17}
Student{name='abc', age=16}
Student{name='jack', age=16}
Student{name='mark', age=16}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-29 11:53:53  更:2021-07-29 11:54:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 15:03:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码