【Java数据结构】初识集合框架——List的使用(附加自动发牌案例)

简介: 笔记

10.png【Java数据结构】初识集合框架——List的使用(附加自动发牌案例)

泛型

          什么是泛型

         泛型的分类

         泛型的定义简单演示

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

        泛型类的使用

        泛型总结

包装类

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

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

List的使用

     List常用方法

     使用示例

自动发牌案例


泛型


什么是泛型

泛型:

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


优点:

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


泛型的分类

泛型类

泛型方法


泛型的定义简单演示

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

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

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

   public class MyArrayList<E> { 
   private E[] array; 
   private int size;
    ... 
    }


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


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


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


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


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


泛型的意义:

①在存储元素的时候,可以自动进行类型检查

②在获取元素的时候,可以进行自动类型的转换


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


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


面试问题:


泛型到底是怎么编译的?

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

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


泛型类的使用

// 定义了一个元素是 Book类 引用的 MyArrayList 
MyArrayList<Book> books = new MyArrayList<Book>(); 
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<Person> 和 MyArrayList<Book> 在运行期间是一个类型。

泛型是 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)


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

11.png

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

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



List的使用


List常用方法13.png


使用示例

import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
public class ListDemo {
    public static void main(String[] args) {
        List<String> 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<String> subCourses = courses.subList(1, 3);
        System.out.println(subCourses);
        // 重新构造
        List<String> courses2 = new ArrayList<>(courses);
        System.out.println(courses2);
        List<String> courses3 = new LinkedList<>(courses);
        System.out.println(courses3);
        // 引用的转换
        ArrayList<String> courses4 = (ArrayList<String>)courses2;
        System.out.println(courses4);
        //LinkedList<String> c = (LinkedList<String>)course2; 错误的类型
        LinkedList<String> courses5 = (LinkedList<String>)courses3;
        System.out.println(courses5);
        //ArrayList<String> c = (ArrayList<String>)course3; 错误的类型
        }
    }

运行结果如下:

14.png


自动发牌案例


分为三个java文件

import java.util.ArrayList;
import java.util.List;
public class TestDemo {
    public static void main(String[] args) {
        List<Card> 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<List<Card>> 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<Card> buyDeck() {
        List<Card> deck = new ArrayList<>(52);
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j <= 13; j++) {
                String suit = suits[i];
                int rank = j;
                deck.add(new Card(rank, suit));//顺序表默认是尾插
            }
        }
        return deck;
    }
    public static void swap(List<Card> deck, int i, int j) {
        Card temp = deck.get(i);
        deck.set(i, deck.get(j));
        deck.set(j, temp);
    }
    public static void shuffle(List<Card> 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);
        }
    }


相关文章
|
4月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
63 1
|
4月前
|
存储 Java
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
113 2
|
4月前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
117 2
|
1月前
|
存储 算法 测试技术
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
42 7
|
2月前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
60 5
|
3月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
68 6
|
3月前
|
存储 Java 索引
Java中的数据结构:ArrayList和LinkedList的比较
【10月更文挑战第28天】在Java编程世界中,数据结构是构建复杂程序的基石。本文将深入探讨两种常用的数据结构:ArrayList和LinkedList,通过直观的比喻和实例分析,揭示它们各自的优势与局限,帮助你在面对不同的编程挑战时做出明智的选择。
|
3月前
|
存储 消息中间件 NoSQL
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。
|
4月前
|
存储 算法 Java
Java 中常用的数据结构
【10月更文挑战第20天】这些数据结构在 Java 编程中都有着广泛的应用,掌握它们的特点和用法对于提高编程能力和解决实际问题非常重要。
51 6
|
4月前
|
安全 Java 程序员
深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制
本文介绍了 Java 中 List 的遍历和删除操作,重点讨论了快速失败(fail-fast)和安全失败(fail-safe)机制。通过普通 for 循环、迭代器和 foreach 循环的对比,详细解释了各种方法的优缺点及适用场景,特别是在多线程环境下的表现。最后推荐了适合高并发场景的 fail-safe 容器,如 CopyOnWriteArrayList 和 ConcurrentHashMap。
99 5

热门文章

最新文章