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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Java---day13_集合框架02 -> 正文阅读

[数据结构与算法]Java---day13_集合框架02

Java—day13_集合框架02

泛型

**定义:**泛型,指的是“泛指的类型”,将数据类型参数化。

好处:

  • 用于集合中,限制了存储的元素的类型,不用在使用元素的时候,逐个元素进行类型检查,简化代码
  • 可以提高代码的可读性
  • 可以使某些发生在运行时期的逻辑错误问题,提前到编译时期,提高效率。

泛型的定义方式:

泛型,是定义在一堆尖括号里面的。在尖括号里面定义一个类型。此时,定义在这一对尖括号中的类型,就是泛型。

  • 泛型,是一个标识符,遵循大驼峰命名法。
  • 泛型,一般情况下,不用太长的类型来描述。(即只需要使用一个字母代替即可)
  • 如果需要定义多种泛型,直接在尖括号中定义,泛型与泛型之间以逗号分隔即可。

泛型指定类型:

在使用到泛型类、接口、方法的时候,指派每一个泛型具体是什么类型。

ps:泛型类型的指派,只能是引用数据类型。泛型不能设置为基本数据类型。如果真的需要使用到基本数据类型,使用他们对应的包装类。

泛型在类中的使用【会】

语法:在类名的后面,紧跟上一尖括号。

class Animal <T> {}
class Dog <T, M> {}

泛型类的使用:声明引用、实例化对象、被继承

// 1. 声明引用
Animal<String> animal;
// 2. 实例化对象
Animal<Integer> animal = new Animal<>();
// 3. 被继承
class Dog extends Animal<String> {}
class Dog<T> extends Animal<T> {}

泛型类的特点:

  • 在类中定义的泛型,虽然还不明确是什么类型,但是在当前类中是可以使用的
  • 在使用到这个类的时候,必须要指定泛型的类型。如果不指定,默认是Object
  • 泛型,只能在当前的类中使用,不能在其他的类中使用,包括子类。
public class Test {
    public static void main(String[] args) {
        // 实例化一个对象
        // 指定了泛型的类型是 String 类型
        Person<String> xiaoming = new Person<>();
        // 泛型,是在编译前期进行的类型检查。一旦编译完成,泛型就不存在
了。
        xiaoming.part = "xiaoming";
 
        Person<Integer> xiaohong = new Person<>();
        xiaohong.part = 2;
 
        // 实例化一个子类对象
        Student student = new Student();
        student.part = "abc";
 
        // 实例化一个泛型子类对象
        Teacher<Integer> xiaowang = new Teacher<>();
        xiaowang.part = 132;
 
        // 如果多个泛型,使用这个类的时候,逐个进行类型指派即可
        Animal<String, Integer> animal = new Animal<>();
 
        // 如果对于一个泛型类,在使用的时候,没有指派类型,默认是 Object 类型
        Person xiaobai = new Person();
    }
}
 
class Animal<T, M> { }
class Person<T> {
    String name;
    int age;
    //在类上确定的泛型可以直接在类的内部使用
    T part;     // 虽然现在还不明确T是什么类型,但是我们可以使用这个类型。
}
 
class Student extends Person<T> {}
 
class Teacher<T> extends Person<T> { }

泛型在接口中的使用【会】

**泛型接口的定义:**在接口名字的后面,添加上一对尖括号。在尖括号里面定义泛型

interface MyInterface<T> {}
interface MyInterface<T, M> {}

**泛型接口的使用:**实现类实现接口、使用接口访问接口中的静态成员、被继承。

// 1. 实现类实现接口
class MyInterface1Impl implements MyInterface1<Person> {}
// 2. 被继承
interface SubMyInterface extends MyInterface1<String> {}

知类使用接口泛型

两种情况

  • 子类与接口泛型一致,接口可以直接使用泛型类型
  • 接口使用泛型,子类不用,在实现的接口位置必须指定一个具体的数据类型
public class Demo9 {
    public static void main(String[] args) {
        Bird<String> bird = new Bird();
        bird.show("haha");
    }
}
 
interface  Inter<E>{
    public void  show(E e);
}
//1.子类与接口一致
/* 类上的泛型确定了,接口上的泛型就确定了,方法上的泛型就确定了
 */
class  Bird<E> implements  Inter<E>{
    @Override
    public void show(E e) {
 
    }
}
 
//2.接口使用泛型,子类不用
/*在实现的接口位置必须指定一个具体的泛型
 *
 * 方法使用泛型的情况:
 * 1.如果是重写的方法,泛型与接口一致
 * 2.如果是子类自己的方法,可以与接口一致,也可以有自己的泛型
 */
class  Cat implements  Inter<String>{
    @Override
    public void show(String s) {
 
    }
}
 
class  Pig implements  Comparable<Pig>{
    @Override
    public int compareTo(Pig o) {
        return 0;
    }
}
 
class ComWithA implements Comparator<String>{
    @Override
    public int compare(String o1, String o2) {
        ArrayList list = null;
        return 0;
    }
}

泛型在方法中的使用【会】

语法:泛型方法中, 在定义方法时,在返回值前面通过定义泛型。

public static <T> void test(T t) {
    
}
  • 在定义处的<>用来定义泛型
  • 在调用处的<>用来使用泛型

泛型方法的分类

  • 方法上的泛型与类上的一致
  • 方法上是独立使用泛型
    • 在方法中定义的泛型,虽然还不明确是什么类型,但是在当前方法中是可以使用的
    • 泛型方法,在使用的时候,不能跟类、接口似的,手动设置类型。泛型方法中,泛型的设置,在参数中体现
    • 泛型方法,一定需要是有参的。参数列表中,必须有泛型类型。
    • 泛型方法中的泛型的设置,是通过在调用方法的时候,实参的类型推导出来的
    • 泛型,只能在当前的方法中使用,不能再其他的方法中使用
  • 静态方法使用泛型

List

ArrayListLinkedList对比【会】

  • 相同点:
    • 都是List集合的常用的实现类
    • 对集合中的元素操作的方法基本一致。
    • 都是线程不安全的。
  • 不同点:
    • ArrayList底层实现是数组,使用数组这种数据结构进行数据的存储。
    • LinkedList底层实现是双链表,使用双链表这种数据结构进行数据的存储。

数据和链表的结果特点比较

  • 数组实现功能时查找快,添加删除慢
  • 链表查找慢,添加删除快

ArrayListLinkedList的使用场景

  • 如果对集合中的元素,增删操作不频繁,查询频繁(使用ArrayList
  • 如果对集合中的元素,增删操作比较频繁,查询操作不频繁(使用LinkedList

集合对自定义对象的存储【会】

  • 类分成系统类和自定义类
  • 系统类往往已经重写了toString(),equals(),``hashcode()等方法
  • 自定义类,为了实现我们的功能,往往我们需要重写父类的常用方法,比如toString(),equals(),``hashcode()
//List默认是有序可重复的---利用Contains
/*
将各学科名字(java,python,python,iOS,bigdata)存入集合,注意名字里面有重复,
要求使用List存储数据,但是数据不能重复
*/
public class Demo6 {
    public static void main(String[] args) {
        test1();
    }
 
    public  static  void  test1(){
        ArrayList list1 = new ArrayList();
        list1.add("java");
        list1.add("python");
        list1.add("python");
        list1.add("iOS");
        list1.add("bigdata");
        System.out.println(list1);
 
        //创建临时集合
        ArrayList list2 = new ArrayList();
 
        Iterator i = list1.iterator();
        while (i.hasNext()){
            Object o = i.next();
            if (!(o instanceof  String)){
                throw  new ClassCastException();
            }
 
            //向下转型
            String s = (String)o;
 
            if (!list2.contains(s)){
                //当list1中不包换object时,将它添加进来
                /*
                 * 如果判断成立,说明list1中不包含当前的元素
                 * 工作原理:当添加元素时,会让当前的元素与集合中已有的元
素通过equels方法进行一一比较.过程中
                 * 只要有一次返回true,停止比较.让整个的contains方法返
回true.只有所有的比较都返回false,最终才会返回false
                 *
                 * 实例:添加第三个元素的时候,调用equals方法的过程
                 * 第三元素.equals("java") = false     第三元
素.equals("python") = true  停止比较
                 */
                list2.add(s);
            }
        }
        System.out.println(list2);
    }
/*
将人类的对象存储到集合中,并按照年龄和姓名比较,相同则认为是同一个人
分析:
如果直接将Person对象存入list,不会按照年龄和姓名去重,因为Person没有重写
Object类的equals方法,默认比较的是对象地址,所以此时需要重写equals方法,在方法
内部按照年龄和姓名比较.
*/

public  static  void  test2(){
        ArrayList list1 = new ArrayList();
        list1.add(new Person("zhangsan",20));
        list1.add(new Person("lisi",20));
        list1.add(new Person("lisi",20));
        list1.add(new Person("wangwu",204));
 
        System.out.println(list1);
 
        ArrayList list2 = new ArrayList();
 
        Iterator i = list1.iterator();
        while (i.hasNext()){
            Object o = i.next();
            if (!(o instanceof  Person)){
                throw  new ClassCastException();
            }
            //向下转型
            Person s = (Person)o;
 
            if (!list2.contains(s)){
                list2.add(s);
            }
        }
        System.out.println(list2);
    }
 
}
 
class  Person{
    String name;
    int age;
 
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
 
    //重写equals方法
 
    @Override
    //自己制定的比较规则:并按照年龄和姓名比较,相同则认为是同一个人
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return 
false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

LinkedList【会】

LinkedList的特有方法对比:

  • jdk1.6之前的删除的获取方法,拿不到元素报异常
  • jdk1.6之后的删除的获取方法,拿不到元素返回null

数据结构【了解】

数据结构的定义

数据结构是计算机存储、组织数据的方式,是相互之间存在一种或多种特定关系的数
据元素的集合,即带“结构”的数据元素的集合。“结构”就是指数据元素之间存在的关
系,分为逻辑结构存储结构.通常情况下,精心选择的数据结构可以带来更高的运
行或者存储效率。

数据的逻辑结构和物理结构是数据结构的两个密切相关的方面,同一逻辑结构可以对
应不同的存储结构。算法的设计取决于数据的逻辑结构,而算法的实现依赖于指定的
存储结构

数据的逻辑结构

指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前
后间关系,而与他们在计算机中的存储位置无关。逻辑结构包括:

  • 集合:数据结构中的元素之间除了”同属一个集合"的相互关系外,别无其他关系;
  • 线性结构:数据结构中的元素存在一对一的相互关系
  • 树形结构:数据结构中的元素存在一对多的相互关系
  • 图形结构:数据结构中的元素存在多对多的相互关系。

数据的物理结构

指数据的逻辑结构在计算机存储空间的存放形式。

常用的数据结构

ps:这里的数据结构分类是从逻辑结构上进行的.

  • 数组(Array)

数组是一种聚合数据类型,它是将具有相同类型的若干变量有序地组织在一起的集
合。数组可以说是最基本的数据结构,在各种编程语言中都有对应。一个数组可以分
解为多个数组元素,按照数据元素的类型,数组可以分为整型数组、字符型数组、浮
点型数组、指针数组和结构数组等。数组还可以有一维、二维以及多维等表现形式。

  • 栈( Stack)

栈是一种特殊的线性表,它只能在一个表的一个固定端进行数据结点的插入和删除操
作。栈按照后进先出的原则来存储数据,也就是说,先插入的数据将被压入栈底,最
后插入的数据在栈顶,读出数据时,从栈顶开始逐个读出。栈在汇编语言程序中,经
常用于重要数据的现场保护。栈中没有数据时,称为空栈

  • 队列(Queue)

队列和栈类似,也是一种特殊的线性表。和栈不同的是,队列只允许在表的一端进行
插入操作,而在另一端进行删除操作(栈按照先出先出的原则来存储数据)。一般来说,进行插入操作的一端称为队尾,进行删除操作的一端称为队头。队列中没有元素时,称为空队列。

  • 链表( Linked List)

链表是一种数据元素按照链式存储结构进行存储的数据结构,这种存储结构具有在物
理上存在非连续的特点。链表由一系列数据结点构成,每个数据结点包括数据域和指
针域两部分。其中,指针域保存了数据结构中下一个元素存放的地址。链表结构中数
据元素的逻辑顺序是通过链表中的指针链接次序来实现的。

  • 树( Tree)

树是典型的非线性结构,它是包括,2个结点的有穷集合K。在树结构中,有且仅有
一个根结点,该结点没有前驱结点。在树结构中的其他结点都有且仅有一个前驱结
点,而且可以有两个后继结点,m≥0。

  • 图(Graph)

图是另一种非线性数据结构。在图结构中,数据结点一般称为顶点,而边是顶点的有
序偶对。如果两个顶点之间存在一条边,那么就表示这两个顶点具有相邻关系。

  • 堆(Heap)

堆是一种特殊的树形数据结构,一般讨论的堆都是二叉堆。堆的特点是根结点的值是
所有结点中最小的或者最大的,并且根结点的两个子树也是一个堆结构。

  • 散列表(Hash)

散列表源自于散列函数(Hash function),其思想是如果在结构中存在关键字和T相等
的记录,那么必定在F(T)的存储位置可以找到该记录,这样就可以不用进行比较操作
而直接取得所查记录。

关于java中?的使用总结(了解)

  • 用于?: 这里是三目运算符一部分,前面是判断条件,后面是两个分支结果
  • 用于数据库的sql语句 select * from emp where name=?:表示占位符
  • 用于泛型,是通配符,表示任何一种数据类型
//这里的Object与前面的?没有关系
    Class<?> class1 = Object.class;
 
    //如果类的泛型使用时写成?是可以的.作为返回值时,会默认成Object类型,但
是作为参数不行.
    //所以在给对象指定泛型时要写具体类型
    Test<?> test = new Test();
 
    //test.run(new Object());
class Test<T>{
     T e;
    public T run(T a) {
        T t = null;
        return t;
    }
}

限制上限<? extends E>(了解)

定义:限制的是整个的<>可以取的泛型类型的上限是E,<>中可以取的类型是E及E的子类

public class Demo10
{
    public static void main(String[] args) {
        //
        ArrayList<Student2> list1 = new ArrayList<>();
        list1.add(new Student2("bingbing", 1));
        //可以传参:因为Student2是Person4的子类,可以实现遍历
        bianli(list1);
 
        ArrayList<Teacher> list2 = new ArrayList<>();
        list2.add(new Teacher("bingbing", 1));
        //可以传参:因为Teacher是Person4的子类,可以实现遍历
        bianli(list2);
 
        ArrayList<Person4> list3 = new ArrayList<>();
        list3.add(new Person4("bingbing", 1));
        //可以传参
        bianli(list3);
 
        ArrayList<Object> list4 = new ArrayList<>();
        list4.add(new Object());
        //可以传参:因为Object是Person4的父类,不可以实现遍历
        //bianli(list4);
    }
 
 
    public static void bianli(Collection<? extends Person4> e){
        System.out.println("遍历了");
    }
}
 
class Person4{
    String name;
    int age;
    public Person4() {
    super();
        // TODO Auto-generated constructor stub
    }
    public Person4(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person4 [name=" + name + ", age=" + age + "]";
    }
}
 
class Teacher extends Person4{
    public  Teacher(String name, int age) {
        super(name, age);
    }
}
 
class Student2 extends Person4 {
    public  Student2(String name, int age) {
        super(name, age);
    }
}

限制下限<? super E>(了解)

定义:限制的是整个的<>可以取的泛型类型的下限是E,<>中可以取的类型是E及E的父类

public class Demo11 {
    public static void main(String[] args) {
        //限制下限 <? super E>
        //TreeSet(Comparator<? super E> comparator) :这里的E跟
TreeSet后面的泛型类型一致,所以现在E应该表示的Student3
 
        //创建Student3类的比较器对象
        ComWithStu comWithStu = new ComWithStu();
        //创建Teacher1类的比较器对象
        ComWithTea comWithTea = new ComWithTea();
        //创建Person1类的比较器对象
        ComWithPerson1 comWithPerson = new ComWithPerson1();
        //创建GoodStudent类的比较器对象
        ComWithGood comWithGood = new ComWithGood();
 
        TreeSet<Student3> set = new TreeSet<>(comWithStu);//因为
这里限制的是Student3及他的父类
        //TreeSet<Student3> set = new TreeSet<>(comWithTea);//不
可以使用,因为Teacher2类与Student3类没有关系
        //TreeSet<Student3> set = new TreeSet<>
(comWithPerson);//可以  ,因为Person3类是Student3类的父类
        //TreeSet<Student3> set = new TreeSet<>(comWithGood);//
不可以,因为GoodStudent类是Student3类的子类
        set.add(new Student3("bingbing"));
        set.add(new Student3("bingbing1"));
        set.add(new Student3("bingbing2"));
    }
}
 
//创建Student3类的比较器
class ComWithStu implements Comparator<Student3> {
 
    public int compare(Student3 o1, Student3 o2) {
 
        return o1.name.compareTo(o2.name);
    }
}
//创建Teacher2类的比较器
class ComWithTea implements Comparator<Teacher2>{
    public int compare(Teacher2 o1, Teacher2 o2) {
 
        return 0;
    }
}
//创建Person2类的比较器
class ComWithPerson1 implements Comparator<Person3>{
    @Override
    public int compare(Person3 o1, Person3 o2) {
        // TODO Auto-generated method stub
        return 0;
    }
    }
 
//创建GoodStudent类的比较器
class ComWithGood implements Comparator<GoodStudent>{
    public int compare(GoodStudent o1, GoodStudent o2) {
        return 0;
    }
}
 
 
class Person3{
    String name;
 
    public Person3(String name) {
        super();
        this.name = name;
    }
 
    public String toString() {
        return "Person3 [name=" + name + "]";
    }
}
 
class Teacher2 extends Person3{
    public Teacher2(String name) {
        super(name);
    }
}
class Student3 extends Person3{
    public Student3(String name) {
        super(name);
    }
}
 
class GoodStudent extends Student3{
    public GoodStudent(String name) {
        super(name);
    }
}

Collections工具类【会】

package day22.dCollections;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class CollectionsUsage {
    public static void main(String[] args) {
        // 1. 实例化一个List集合对象
        List<Integer> list = new ArrayList<>();
 
        // 2. 添加元素
        Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
 
        // 3. 获取一个集合中的最大值,大小比较通过元素对应的类实现的
Comparable接口进行比较
        Integer max = Collections.max(list);
        //    获取一个集合中的最大值,大小比较通过第二个参数 Comparator
        Integer max2 = Collections.max(list, (i1, i2) -> i2 - 
i1);
 
        // 4. 获取一个集合中的最小值,大小比较通过元素对应的类实现的
Comparable接口进行比较
        Integer min = Collections.min(list);
        //    获取一个集合中的最小值,大小比较通过第二个参数 Comparator
        Integer min2 = Collections.min(list, (i1, i2) -> i2 - 
i1);
 
        // 5. 将List集合中的数据进行随机的排列(洗牌)
        Collections.shuffle(list);
 
        // 6. 交换一个List集合中两个下标对应的元素
        Collections.swap(list, 0, 2);
        // 7. 将一个List集合中的元素倒序排列
        Collections.reverse(list);
 
        // 8. 将一个List集合进行排序,元素的大小比较规则使用元素对应的类
实现的Comparable接口进行比较大小
        Collections.sort(list);
        //    将一个List集合按照指定的规则进行升序排序,基本不用,List集
合中本身就有这样的排序方法
        Collections.sort(list, (i1, i2) -> i2 - i1);
 
        // 9. 集合中的元素拷?,将作为第二个参数的集合中的数据拷?到第一个
集合中
        List<Integer> copy = new ArrayList<>();
        Collections.addAll(copy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
        Collections.copy(copy, list);
 
        // 10. 使用指定的数据,填充一个集合
        Collections.fill(list, 0);
 
        // 11. 将线程不安全的集合,转成线程安全的集合
        // Collections.synchronizedCollection()
        // Collections.synchronizedList()
        // Collections.synchronizedSet()
        // Collections.synchronizedMap()
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 11:27:45  更:2021-08-03 11:28:48 
 
开发: 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/10 6:17:12-

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