Java高级学习-泛型

举报
AAAI 发表于 2021/04/02 04:54:54 2021/04/02
【摘要】 泛型 是一种未知的数据类型 (E) ,也可以看作是一个变量,用来接收数据类型。 E e : Element 元素 T t : Type 类型 创建集合对象的时候,就会确定泛型的数据类型。ArrayList 把数据类型作为参数传递,赋给泛型E。 创建集合对象不使用泛型,可以存储任意类型数据,不安全,可能会发生异常。 使用泛型好处: 避免类型转换麻烦将运行期...

泛型

是一种未知的数据类型 (E) ,也可以看作是一个变量,用来接收数据类型。

E e : Element 元素

T t : Type 类型

创建集合对象的时候,就会确定泛型的数据类型。ArrayList

把数据类型作为参数传递,赋给泛型E。

创建集合对象不使用泛型,可以存储任意类型数据,不安全,可能会发生异常。

使用泛型好处:

避免类型转换麻烦将运行期异常,提升到编译器。

弊端:泛型是什么类型,只能存储什么类型的数据。

泛型的定义

不确定使用什么数据类型时,使用泛型。

泛型可以接受任意类型的数据,自定义的类也可以 Student

不写泛型默认为Object类型。

public class 类名 { 方法; }

类名<类型> 对象名 = new 类名<>( );

继承:

public class 类名 extends A { }

含有泛型的方法

泛型定义的方法在修饰符和返回值类型之间。

修饰符 <泛型> 返回值类型 方法名 (参数列表(使用泛型) ) { 方法体; }

public void demo ( M m ) { m.xxx; }

直接传递参数

含有泛型的静态方法:

public static void demo ( M m ) { m.xxx; }

静态方法,不建议创建对象,使用类名.静态方法名( xx ); 进行使用。

含有泛型的接口:

public interface Demo { 抽象方法;E next();E get();add(E e); }

使用方式:

定义接口实现类,指定接口的泛型 : xx implements Demo

接口使用什么泛型,实现类就使用什么泛型,相当于定义了一个含有泛型的类。

public class 类名 extends A implements Demo { }

类名<类型> 对象名 = new 类名<>( );

泛型通配符

未知通配符:不知道使用什么类型接受数据,只能接受,不能存储数据。

使用:遍历集合

?代表任务的数据类型,只能作为方法的参数使用

public  static  void printA (ArrayList<?>  list) {  
//使用迭代器遍历:
Iterator<?> it  =  list.iterator();
while(it.hasNext( ) ){ Object  o  =  it.next();
}  }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意:定义时不能使用:ArrayList<?> x = new ArrayList<?> () ; 错误

受限泛型

泛型的上限:只能接受该类型及其子类,? extends E

类型名 <? extends 类 > 对象名称

泛型的下限:只能接受该类型及其父类:? super E

类型名 <? super 类 > 对象名称

数据结构

栈:先进后出,LinkedList stack = new LinkedList<>();

stack.addLast(1); stack.removeLast(); // 出栈

队列:先进先出,Queue queue = new LinkedList<>();

queue.offer(1); // 元素 1 入队 queue.poll(); // 出队 -> 元素 1

数组,查询快(数组的地址是连续的),增删慢(数组长度固定不变,添加要复制新数组,,再把新数组地址赋值给变量,原数组进行垃圾回收)

int[] a = new int[3]{1,2,3,4};

链表:查询慢(每一个元素为一个节点,一个节点包含数据源+两个指针域,自己的地址和下一个节点地址),增删快。LinkedList:List接口的链表实现

单向链表:不能保证元素顺序

双向链表:有一个链子是记录顺序的,是有序的集合

红黑树:

二叉树:分支不能超过两个孩子

排序树/查找树:在二叉树的基础上,元素的是有顺序的。左子树小,右子树大。

平衡二叉树:左孩子数量==右孩子数量

红黑树:特点:趋近于二叉树,查询速度非常快,查询叶子节点最大次数和最小次数不能超过2倍。

约束:节点可以是红色或者黑色的,

根节点是黑色的,

叶子节点是黑色的,

每一个红色的节点的子节点都是黑色的

任何一个节点到每一个叶子节点的所有路径上的黑色节点数量相同。

List集合

java.util.list

Collection集合的子类,List接口继承Collection接口

1.有序的集合 2.有索引3.允许存储重复数据

创建多态:List list = ArrayList<>();

list.add(int index, E element)

E remove(int index) //返回被移除的元素

E set(int index) // 替换集合中指定位置的元素,返回被替换的元素

E get(int index)

List遍历

for:list.size().fori

迭代器:Iterator it = new Iterator<>();

while(it.hasNext( ) ) { it.next(); }

增强for即foreach

List.for

防止索引越界:IndexOutOfBoundException,集合会报错

List子类

ArrayList集合查找快,增删慢。 结构是数组结构。

ArrayList<Person>  list = new ArrayList<>();
list .add( new Person("XXX" , 11));

  
 
  • 1
  • 2

LinkedList:List接口的链表实现,双向链表,查询慢,增删快,包含了对首尾操作的方法,使用特有方法时不能使用多态。

添加元素:addFirst列表开头插入== push ( ) ,addLast列表结尾插入== add,

获取元素:getFirst(),getLast()

清空元素:clean()

isEmpty是否为空

removeFirst( ) == pop( ),removeLast( )

Set集合

不包含重复元素的集合,没有索引,不能使用for循环

HashSet

实现了set接口,是一个无序的结合,存储元素和取出元素顺序可能不同

底层是一个哈希表(HashMap)结构,查询非常快

Set s = new HashSet<>();

HashSet s = new HashSet<>();

使用迭代器进行遍历

迭代器:Iterator it = new Iterator<>();

while(it.hasNext( ) ) { it.next(); }

增强for:

哈希值

是一个十进制的整数,系统随机给出,对象的地址值,是一个逻辑地址,是模拟出来的,不是实际的物理地址。

Object类的方法,获取哈希值:int hashCode()

hashCode的源码:public native int hashCode(),native调用本地操作系统的方法。

toString返回的是hashCode的十六进制的值。不是实际的物理地址

String类的哈希值:重写了Object的hashCode的方法。

哈希表结构

HashSet集合存储数据的结构,查询速度快。

哈希表 = 数组 + 链表

哈希表 = 数组 + 红黑树

数组把元素进行分组,相同的哈希值是同一组,链表/红黑树将这些组进行连接到一起,挂到当前哈希值数组下。

哈希冲突:两个元素不同,但是哈希值相同。

如果链表的长度超过8位数,将链表转换为红黑树,提升查询效果

Set集合元素不重复

出现哈希冲突,使用equals进行判断元素地址值,如果元素地址相同,就不存储进去。如果元素不相同,就存储进去。使用链表或者红黑树进行挂在同一个哈希值下面。

HashSet存储自定义类型元素

必须重写hashCode方法和equals方法,因为要比较值

在自定义类中进行重写。

LinkedHashSet

定义了迭代顺序,是双向列表,记录元素的存储顺序,保证元素有序,且元素不重复

LinkedHashSet s = new LinkedHashSet<>();

可变参数

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

等价于:修饰符 返回值类型 方法名 (参数类型 [ ] 形参名) { }

使用环境:当方法的参数列表数据类型已去掉,参数个数不确定。

原理:底层是一个数组,根据传递参数个数的不同,创建不同长度数组,存储参数。

public static  int  add ( int ... arr) {
int sum = 0;
for (int i : arr) { sum += i ; }
return sum; }

  
 
  • 1
  • 2
  • 3
  • 4

调用add ( ) 会创建一个长度为0的数组 arr,new int [ 0 ]

注意:

1.一个方法的参数列表,只能有一个可变参数

2.如果方法的参数有多个,可变参数写在参数列表末尾

3.特殊写法:public static void method ( Object … obj) { }

Collections

集合工具类,对集合进行操作

随机排序:shuffle(List) Collections.shuffle( );

public static boolean addAll ( Collection c, T … elements) 添加一些元素

: Collections.addAll (list , 1, 2, 3);

public static void sort ( List list) 默认升序 :Collections.sort(list);

sort 使用前提:被排序的集合里面存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序规则。

例如:

public class Person  implements  Comparable<Person> { 
@Override
public int compareTo(Person o){
//自定义比较规则
	return  this.getAge - o.getAge ( ) ; // 年龄升序排序
}  }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Comparable排序规则:自己(this)- 参数:升序,参数- 自己(this):降序this - o > 0 ,则compareTo返回这个数,sort进行升序排列,把o的值放在序列前面

sort (List , Comparator)

public static void sort ( List list,Comparator<? super T>)

传一个集合和一个比较器

Comparable与Comparator

Comparable:自己(this)与别人(参数)进行比较,自己需要实现Comparable接口,重写比较规则compareTo方法,强行对实现它的每个类的对象进行整体排序。

Comparator:找到第三方的裁判进行比较,强行对某个对象进行整体排序。

Comparator要重写compare< T o1, T o2> 方法,o1 - o2 升序

Arrary.sort( list, new Comparator<Person> { 
@Override
public int compare(Person o1, Person o2){
//自定义比较规则
	return  o1.getAge() - o2.getAge () ; // 年龄升序排序
}  } ); //匿名内部类 new 接口()


//lambda
Arrary.sort( list, (o1, o2) -> o1.getAge() - o2.getAge( ) ); //匿名内部类 new 接口()

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

文章来源: blog.csdn.net,作者:αβγθ,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_38022166/article/details/115381884

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。