Java—day13_集合框架02
泛型
**定义:**泛型,指的是“泛指的类型”,将数据类型参数化。
好处:
- 用于集合中,限制了存储的元素的类型,不用在使用元素的时候,逐个元素进行类型检查,简化代码
- 可以提高代码的可读性
- 可以使某些发生在运行时期的逻辑错误问题,提前到编译时期,提高效率。
泛型的定义方式:
泛型,是定义在一堆尖括号里面的。在尖括号里面定义一个类型。此时,定义在这一对尖括号中的类型,就是泛型。
- 泛型,是一个标识符,遵循大驼峰命名法。
- 泛型,一般情况下,不用太长的类型来描述。(即只需要使用一个字母代替即可)
- 如果需要定义多种泛型,直接在尖括号中定义,泛型与泛型之间以逗号分隔即可。
泛型指定类型:
在使用到泛型类、接口、方法的时候,指派每一个泛型具体是什么类型。
ps: 泛型类型的指派,只能是引用数据类型。泛型不能设置为基本数据类型。如果真的需要使用到基本数据类型,使用他们对应的包装类。
泛型在类中的使用【会】
语法:在类名的后面,紧跟上一尖括号。
class Animal <T> {}
class Dog <T, M> {}
泛型类的使用:声明引用、实例化对象、被继承
Animal<String> animal;
Animal<Integer> animal = new Animal<>();
class Dog extends Animal<String> {}
class Dog<T> extends Animal<T> {}
泛型类的特点:
- 在类中定义的泛型,虽然还不明确是什么类型,但是在当前类中是可以使用的
- 在使用到这个类的时候,必须要指定泛型的类型。如果不指定,默认是Object
- 泛型,只能在当前的类中使用,不能在其他的类中使用,包括子类。
public class Test {
public static void main(String[] args) {
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<>();
Person xiaobai = new Person();
}
}
class Animal<T, M> { }
class Person<T> {
String name;
int age;
T part;
}
class Student extends Person<T> {}
class Teacher<T> extends Person<T> { }
泛型在接口中的使用【会】
**泛型接口的定义:**在接口名字的后面,添加上一对尖括号。在尖括号里面定义泛型
interface MyInterface<T> {}
interface MyInterface<T, M> {}
**泛型接口的使用:**实现类实现接口、使用接口访问接口中的静态成员、被继承。
class MyInterface1Impl implements MyInterface1<Person> {}
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);
}
class Bird<E> implements Inter<E>{
@Override
public void show(E e) {
}
}
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
ArrayList 与LinkedList 对比【会】
- 相同点:
- 都是List集合的常用的实现类
- 对集合中的元素操作的方法基本一致。
- 都是线程不安全的。
- 不同点:
ArrayList 底层实现是数组,使用数组这种数据结构进行数据的存储。LinkedList 底层实现是双链表,使用双链表这种数据结构进行数据的存储。
数据和链表的结果特点比较
- 数组实现功能时查找快,添加删除慢
- 链表查找慢,添加删除快
ArrayList 与LinkedList 的使用场景
- 如果对集合中的元素,增删操作不频繁,查询频繁(使用
ArrayList ) - 如果对集合中的元素,增删操作比较频繁,查询操作不频繁(使用
LinkedList )
集合对自定义对象的存储【会】
- 类分成系统类和自定义类
- 系统类往往已经重写了
toString() ,equals(),``hashcode() 等方法 - 自定义类,为了实现我们的功能,往往我们需要重写父类的常用方法,比如
toString() ,equals(),``hashcode()
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)){
list2.add(s);
}
}
System.out.println(list2);
}
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 +
'}';
}
@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: 这里的数据结构分类是从逻辑结构上进行的.
数组是一种聚合数据类型,它是将具有相同类型的若干变量有序地组织在一起的集 合。数组可以说是最基本的数据结构,在各种编程语言中都有对应。一个数组可以分 解为多个数组元素,按照数据元素的类型,数组可以分为整型数组、字符型数组、浮 点型数组、指针数组和结构数组等。数组还可以有一维、二维以及多维等表现形式。
栈是一种特殊的线性表,它只能在一个表的一个固定端进行数据结点的插入和删除操 作。栈按照后进先出的原则来存储数据,也就是说,先插入的数据将被压入栈底,最 后插入的数据在栈顶,读出数据时,从栈顶开始逐个读出。栈在汇编语言程序中,经 常用于重要数据的现场保护。栈中没有数据时,称为空栈。
队列和栈类似,也是一种特殊的线性表。和栈不同的是,队列只允许在表的一端进行 插入操作,而在另一端进行删除操作(栈按照先出先出的原则来存储数据)。一般来说,进行插入操作的一端称为队尾,进行删除操作的一端称为队头。队列中没有元素时,称为空队列。
链表是一种数据元素按照链式存储结构进行存储的数据结构,这种存储结构具有在物 理上存在非连续的特点。链表由一系列数据结点构成,每个数据结点包括数据域和指 针域两部分。其中,指针域保存了数据结构中下一个元素存放的地址。链表结构中数 据元素的逻辑顺序是通过链表中的指针链接次序来实现的。
树是典型的非线性结构,它是包括,2个结点的有穷集合K。在树结构中,有且仅有 一个根结点,该结点没有前驱结点。在树结构中的其他结点都有且仅有一个前驱结 点,而且可以有两个后继结点,m≥0。
图是另一种非线性数据结构。在图结构中,数据结点一般称为顶点,而边是顶点的有 序偶对。如果两个顶点之间存在一条边,那么就表示这两个顶点具有相邻关系。
堆是一种特殊的树形数据结构,一般讨论的堆都是二叉堆。堆的特点是根结点的值是 所有结点中最小的或者最大的,并且根结点的两个子树也是一个堆结构。
散列表源自于散列函数(Hash function),其思想是如果在结构中存在关键字和T相等 的记录,那么必定在F(T)的存储位置可以找到该记录,这样就可以不用进行比较操作 而直接取得所查记录。
关于java 中?的使用总结(了解)
- 用于?: 这里是三目运算符一部分,前面是判断条件,后面是两个分支结果
- 用于数据库的
sql 语句 select * from emp where name=? :表示占位符 - 用于泛型,是通配符,表示任何一种数据类型
Class<?> class1 = Object.class;
是作为参数不行.
Test<?> test = new Test();
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));
bianli(list1);
ArrayList<Teacher> list2 = new ArrayList<>();
list2.add(new Teacher("bingbing", 1));
bianli(list2);
ArrayList<Person4> list3 = new ArrayList<>();
list3.add(new Person4("bingbing", 1));
bianli(list3);
ArrayList<Object> list4 = new ArrayList<>();
list4.add(new Object());
}
public static void bianli(Collection<? extends Person4> e){
System.out.println("遍历了");
}
}
class Person4{
String name;
int age;
public Person4() {
super();
}
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) {
TreeSet后面的泛型类型一致,所以现在E应该表示的Student3
ComWithStu comWithStu = new ComWithStu();
ComWithTea comWithTea = new ComWithTea();
ComWithPerson1 comWithPerson = new ComWithPerson1();
ComWithGood comWithGood = new ComWithGood();
TreeSet<Student3> set = new TreeSet<>(comWithStu);
这里限制的是Student3及他的父类
可以使用,因为Teacher2类与Student3类没有关系
(comWithPerson);
不可以,因为GoodStudent类是Student3类的子类
set.add(new Student3("bingbing"));
set.add(new Student3("bingbing1"));
set.add(new Student3("bingbing2"));
}
}
class ComWithStu implements Comparator<Student3> {
public int compare(Student3 o1, Student3 o2) {
return o1.name.compareTo(o2.name);
}
}
class ComWithTea implements Comparator<Teacher2>{
public int compare(Teacher2 o1, Teacher2 o2) {
return 0;
}
}
class ComWithPerson1 implements Comparator<Person3>{
@Override
public int compare(Person3 o1, Person3 o2) {
return 0;
}
}
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) {
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
Comparable接口进行比较
Integer max = Collections.max(list);
Integer max2 = Collections.max(list, (i1, i2) -> i2 -
i1);
Comparable接口进行比较
Integer min = Collections.min(list);
Integer min2 = Collections.min(list, (i1, i2) -> i2 -
i1);
Collections.shuffle(list);
Collections.swap(list, 0, 2);
Collections.reverse(list);
实现的Comparable接口进行比较大小
Collections.sort(list);
合中本身就有这样的排序方法
Collections.sort(list, (i1, i2) -> i2 - i1);
集合中
List<Integer> copy = new ArrayList<>();
Collections.addAll(copy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
Collections.copy(copy, list);
Collections.fill(list, 0);
}
}
|