Java数据结构之List的使用总结

网友投稿 248 2022-09-13


Java数据结构之List的使用总结

目录泛型什么是泛型泛型的分类泛型的定义简单演示泛型背后作用时期和背后的简单原理泛型类的使用泛型总结包装类基本数据类型和包装类直接的对应关系包装类的使用,装箱(boxing)和拆箱(unboxing)List的使用List常用方法使用示例自动发牌案例

泛型

什么是泛型

泛型:即通过参数化类型来实现在同一份代码上操作多种数据类型。泛型是在C#2.0引入的。泛型(Genericity)的字面意思是指具有在多种数据类型上皆可操作的含意,与模板有些相似。

优点:泛型类和泛型方法同时具备可重用性、类型安全和效率,这是非泛型类和非泛型方法无法具备的。泛型通常用与集合以及作用于集合的方法一起使用。

泛型的分类

泛型类

泛型方法

泛型的定义简单演示

1. 尖括号 <> 是泛型的标志

2. E 是类型变量(Type Variable),变量名一般要大写

3. E 在定义时是形参,代表的意思是 MyArrayList 最终传入的类型,但现在还不知道

public class MyArrayList {

private E[] awQFgylexrray;

private int size;

...

}

泛型背后作用时期和背后的简单原理

泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念。

泛型代码在运行期间,就是我们上面提到的,利用 Object 达到的效果(这里不是很准确,后期会专门写一篇博客讲泛型)。

< T > 代表当前类是一个泛型类。

new T[10]; 不能new泛型类型的数组 T[] t = new T[];

泛型的意义: ①在存储元素的时候,可以自动进行类型检查 ②在获取元素的时候,可以进行自动类型的转换

泛型类型的参数:不能是简单类型

泛型类型的参数,是不参与类型的组成的

面试问题:

泛型到底是怎么编译的?

1、泛型只在编译的时候,起作用。在运行的时候,是没有泛型的概念的!!!

2、擦除机制 -> Object -> 不严谨-> 我们可以给定一个擦除边界

泛型类的使用

// 定义http://了一个元素是 Book类 引用的 MyArrayList

MyArrayList books = new MyArrayList();

books.add(new Book());

// 会产生编译错误,Person 类型无法转换为 Book 类型

books.add(new Person());

// 不需要做类型转换

Book book = book.get(0);

// 会产生编译错误,Book 类型无法转换为 Person 类型

Person person = book.get(0);

通过以上代码,我们可以看到泛型类的一个使用方式:只需要在所有类型后边跟尖括号,并且尖括号内是人为限定所需要传入的类型,即 E 可以看作的最后的类型。

注意:

Book 只能想象成 E 的类型,但实际上 E 的类型还是 Object。

java中的泛型仅仅是一个编译时的概念,在运行时,所有的泛型信息都被消除了,这被称为泛型擦除。

泛型总结

泛型是为了解决某些容器、算法等代码的通用性而引入,并且 能在编译期间做类型检查,如果用使用Object类,当传入了非法参数时,编译器是不会报错的。

泛型利用的是 Object 是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。

泛型是一种编译期间的机制,即 MyArrayList 和 MyArrayList 在运行期间是一个类型。

泛型是 java 中的一种合法语法,标志就是尖括号 < >

包装类

Object 引用可以指向任意类型的对象,但有例外出现了,8 种基本数据类型不是对象,那岂不是刚才的泛型机制要失效了?

实际上也确实如此,为了解决这个问题,java 引入了一类特殊的类,即这 8 种基本数据类型的包装类,在使用过程中,会将类似 int 这样的值包装到一个对象中去

基本数据类型和包装类直接的对应关系

基本数据类型

包装类

byte

Byte

short

Short

int

Integer

long

Long

float

Float

double

Double

char

Character

boolean

Boolean

基本就是类型的首字母大写,除了 Integer 和 Character。

包装类的使用,装箱(boxing)和拆箱(unboxing)

有手动装箱 也有 自动装箱,拆箱 也一样

可以看到在使用过程中,装箱和拆箱带来不少的代码量,所以为了减少开发者的负担,java 提供了自动机制。

注意:自动装箱和自动拆箱是工作在编译期间的一种机制

List的使用

List常用方法

方法

解释

boolean

add(E e) 尾插 e

void add(int index, E element)

将 e 插入到 index 位置

boolean addAll(Collection extends E> c)

尾插 c 中的元素

E remove(int index)

删除 index 位置元素

boolean remove(Object o)

删除遇到的第一个 o

E get(int index)

获取下标 index 位置元素

E set(int index, E element)

将下标 index 位置元素设置为 element

void clear()

清空

boolean contains(Object o)

判断 o 是否在线性表中

int indexOf(Object o)

返回第一个 o 所在下标

int lastIndexOf(Object o)

返回最后一个 o 的下标

List subList(int fromIndex, int toIndex)

截取部分 list

使用示例

import java.util.List;

import java.util.ArrayList;

import java.util.LinkedList;

public class ListDemo {

public static void main(String[] args) {

List courses = new ArrayList<>();

courses.add("Kobe");

courses.add("Jordan");

courses.add("Westbrook");

courses.add("Durant");

// 和数组一样,允许添加重复元素

courses.add("Kobe");

// 按照添加顺序打印

System.out.println(courses);

// 类似数组下标的方式访问

System.out.println(courses.get(0));

//给目标位置设置新元素

courses.set(0, "Jordan");

System.out.println(courses);

// 截取部分 [1, 3) 注意这里是左开右闭区区间

List subCourses = courses.subList(1, 3);

System.out.println(subCourses);

// 重新构造

List courses2 = new ArrayList<>(courses);

System.out.println(courses2);

List courses3 = new LinkedList<>(courses);

System.out.println(courses3);

// 引用的转换

ArrayList courses4 = (ArrayList)courses2;

System.out.println(courses4);

//LinkedList c = (LinkedList)course2; 错误的类型

LinkedList courses5 = (LinkedList)courses3;

System.out.println(courses5);

//ArrayList c = (ArrayList)course3; 错误的类型

}

}

运行结果如下:

自动发牌案例

分为三个java文件

import java.util.ArrayList;

import java.util.List;

public class TestDemo {

public static void main(String[] args) {

List deck = CardDemo.buyDeck();

System.out.println("买来的新牌");

System.out.println(deck);

System.out.println("===========================");

CardDemo.shuffle(deck);

System.out.println("洗过后的牌");

System.out.println(deck);

System.out.println("===========================");

//三个人,每个人轮流抓牌,一个人五张牌

List> hands = new ArrayList<>();//二维数组的思维

hands.add(new ArrayList<>());//加一个人

hands.add(new ArrayList<>());//再加一个人

hands.add(new ArrayList<>());//再加一个人,共三个人

for (int i = 0; i < 5 ; i++){

for (int j = 0; j < 3; j++){

hands.get(j).add(deck.remove(0));

//这里的remove返回顺序表里被移除的元素,刚好牌堆里少一张牌

}

}

System.out.println("剩余的牌");

System.out.println(deck);

System.out.println("A手中的牌");

System.out.println(hands.get(0));

System.out.println("B手中的牌");

System.out.println(hands.get(1));

System.out.println("C手中的牌");

System.out.println(hands.get(2));

}

}

public class Card {

private int rank;//牌值

private String suit;//花色

public Card(int rank, String suit) {

this.rank = rank;

this.suit = suit;

}

@Override

public String toString() {

return String.format("[%s %d]", suit, rank);

}

}

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

public class CardDemo {

private static final String[] suits = {"♥", "♠", "♦", "♣"};

//买一副牌

public static List buyDeck() {

List deck = new ArrayList<>(52);

for (int i = 0; i < 4; i++) {

for (int j wQFgylex= 1; j <= 13; j++) {

String suit = suits[i];

int rank = j;

deck.add(new Card(rank, suit));//顺序表默认是尾插

}

}

return deck;

}

public static void swap(List deck, int i, int j) {

http:// Card temp = deck.get(i);

deck.set(i, deck.get(j));

deck.set(j, temp);

}

public static void shuffle(List deck){

Random rand = new Random(20211122);

for (int i = deck.size() - 1; i > 0; i--){

int r = rand.nextInt(i);//生成0~i的随机正整数

swap(deck, i ,r);

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:IP地址和子网划分学习笔记之《超网合并详解》(将网络分隔成多个IP子网)
下一篇:子网划分精讲和可变长子网(VLSM)划分实例分析(vlsm可变长子网掩码技术是为了解决哪些问题)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~