Java进阶学习之集合与泛型(1)
1.集合
1.1.集合是什么
之前的基础篇中我们知道了一种数据结构:数组,可以存放很多数据。但是数据有很大的局限性:
- 支持的数据类型单一
- 声明时需要指定大小,大小固定,可扩展性差
- 连续的存储单元,对内存要求苛刻
那么是否有其他的数据结构或者数据类型用于存储数据以解决数组的局限性呢,集合框架就是如此,也称为容器。
1.2.集合框架结构
集合类型可分为Collection和Map。
1.2.1.Collection
Collection的结构图如下:复杂继承和接口实现

| 接口名 | 描述与作用 | ||
|---|---|---|---|
| Iterator | 迭代器,之前在说增强for循环中有提到过迭代器,是Collection的父接口 | ||
| Collection | 是List、Set和Queue的父接口,存储一组不唯一、无序的对象,一般使用其子接口实现类进行操作数据 | ||
| List | 可通过索引获取对象,存储一组不唯一、有序的对象 | ||
| Set | 存储一组唯一、无序的对象 | ||
| Queue | 队列接口 |
1.2.2.Map
Map地结构图如下:

| 接口名 | 描述与作用 | ||
|---|---|---|---|
| Map | 存储key-value的一组键值对象 |
1.3.集合接口实现类
接下我会选出常用的实现类进行解析。
1.3.1.LinkedList
实现了List接口和Queue接口,即存储一组不唯一、允许null,有序的对象,并且也可作为队列使用。采用链表结构进行实现,便于集合的插入和删除元素,访问元素相对较慢。由于其实现方法没有synchronized关键字修饰,所以是线程不安全的。
例1(正常):
public class TestLinkedList1 {
public static void main(String[] args) {
List<String> linkedList = new LinkedList<>();
//添加元素
linkedList.add("zhangsan");
linkedList.add("lisi");
linkedList.add(null);
linkedList.add(null);
//通过索引获取对象
System.out.println(linkedList.get(0));
System.out.println("------------------");
//使用增强for循环遍历迭代器
for (String name : linkedList) {
System.out.println(name);
}
System.out.println("------------------");
//删除元素
linkedList.remove(null);
for (String name : linkedList) {
System.out.println(name);
}
}
}
执行结果:

例2(当作队列):
public class TestLinkedList2 {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
//添加元素
queue.add("zhangsan");
queue.add("lisi");
System.out.println(queue.peek());
//删除元素
String name = queue.poll();
System.out.println(name);
}
}
执行结果:

遵循队列的先进先出原则。
1.3.2.ArrayList
实现了List接口,存储一组不唯一、允许null,有序的对象。采用大小可变的数组实现,可进行快速的随机访问,即索引访问,但是插入和删除元素较为费时。初始大小为10,也可使用构造器指定大小创建。和LinkedList一样是线程不安全的。
例子:
public class TestArrayList {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("zhangsan");
list.add("lisi");
list.add("lisi");
System.out.println(list.get(0));
System.out.println("--------------");
for (String name : list) {
System.out.println(name);
}
System.out.println("--------------");
list.remove("lisi");
for (String name : list) {
System.out.println(name);
}
}
}
执行结果:

1.3.3.HashSet
实现了Set接口,即存储一组唯一的、无序的、可以为null的对象。由于使用hash算法存储集合元素,因此具有很好的存取和查找的新娘功能。是线程不安全的。
public class TestHashSet {
public static void main(String[] args) {
Set<String> hashSet = new HashSet<>();
hashSet.add("zhangsan");
hashSet.add("zhangsan");
hashSet.add("lisi");
System.out.println(hashSet.size());
System.out.println(hashSet.contains("lisi"));
System.out.println("-------------------");
for (String name : hashSet) {
System.out.println(name);
}
System.out.println("-------------------");
hashSet.remove("zhangsan");
for (String name : hashSet) {
System.out.println(name);
}
}
}
执行结果:

1.3.4.TreeSet
实现了SortedSet接口(该接口继承Set接口),即存储一组唯一的、有序的对象,这里的有序是有条件的,对象需要实现Comparable接口。是线程不安全的。
我们发现Comparable接口中只有一个方法public int compareTo(T o);,则返回对象实现该方法即可。如果当前对象小于、等于和大于方法中的对象,返回负整数、零和正整数。
例子:
public class Person implements Comparable {
private String name;
private int age;
public Person(){}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Person o) {
if (this.age > o.getAge()) {
return 1;
} else if (this.age == o.getAge()) {
return 0;
} else {
return -1;
}
}
}
public class TestTreeSet {
public static void main(String[] args) {
TreeSet<Person> treeSet = new TreeSet<>();
treeSet.add(new Person("zhangsan", 20));
treeSet.add(new Person("lisi", 33));
treeSet.add(new Person("zhangsan2", 20));
treeSet.add(new Person("wanger", 15));
for (Person p : treeSet) {
System.out.println(p);
}
System.out.println("----------------");
treeSet.remove(new Person("lisi2", 33));
for (Person p : treeSet) {
System.out.println(p);
}
}
}
执行结果:

我们使用Person类的age属性作为比较的依据,相同age的即相同对象。当我们插入数据时,会按照age进行升序排列;当删除元素时,按照age相等的进行删除。
1.3.5.HashMap
实现了Map接口,即键值对存储对象,key不可重复,无序,使用hash算法进行存储元素,相同key进行插入时会覆盖原有的值。是线程不安全的。
例子:
public class TestHashMap {
public static void main(String[] args) {
TreeSet<Person> treeSet = new TreeSet<>();
treeSet.add(new Person("zhangsan", 20));
treeSet.add(new Person("lisi", 33));
treeSet.add(new Person("zhangsan2", 20));
treeSet.add(new Person("wanger", 15));
for (Person p : treeSet) {
System.out.println(p);
}
System.out.println("----------------");
treeSet.remove(new Person("lisi2", 33));
for (Person p : treeSet) {
System.out.println(p);
}
}
}
执行结果:

1.3.6.TreeMap
实现了SortedMap接口,故名思意是有序的,key有序、不可为null、不可重复。是线程不安全的。
例子:
public class TestHashMap {
public static void main(String[] args) {
Map<String, String> map = new TreeMap<>();
map.put("zhangsan", "aaaa");
map.put("lisi", "bbbb");
map.put("zhangsan", "cccc");
for (String name : map.keySet()) {
System.out.println(map.get(name));
}
System.out.println("----------------");
map.remove("lisi");
for (String name : map.keySet()) {
System.out.println(map.get(name));
}
}
}
执行结果:

2.泛型
集合框架的优势在于元素通用性。在之前的集合中我们已经遇到了泛型,在Map<String, String> map = new TreeMap<>();中map的key指定为String类,value也指定String类,在TreeMap类定义中public class TreeMap<K,V>这里的K和V就是泛型,泛型提供编译时类型安全检测机制。
例子:
public class TestHashMap {
public static void main(String[] args) {
Integer[] arr1 = {1,2,3,4,5};
Double[] arr2 = {1.1,2.2,3.3,4.4,5.5};
String[] arr3 = {"zhangsan", "lisi", "wanger"};
printArray(arr1);
printArray(arr2);
printArray(arr3);
}
static <E> void printArray(E[] array) {
for (E e : array) {
System.out.println(e);
}
System.out.println("-------------------");
}
}
执行结果:

Java进阶学习之集合与泛型(1)的更多相关文章
- Java进阶学习:将文件上传到七牛云中
Java进阶学习:将文件上传到七牛云中 通过本文,我们将讲述如何利用七牛云官方SDK,将我们的本地文件传输到其存储空间中去. JavaSDK:https://developer.qiniu.com/k ...
- Java进阶学习:log4j的学习和使用
Java进阶学习——log4j的学习和使用 简介Loj4j Log4j的组成 Log4j主要由三大组组件构成: Logger: 负责生成日志,并能够对日志信息进行分类筛选,通俗的讲就是决定什么日志信息 ...
- Android(java)学习笔记89:泛型概述和基本使用
package cn.itcast_01; import java.util.ArrayList; import java.util.Iterator; /* * ArrayList存储字符串并遍历 ...
- Android(java)学习笔记28:泛型概述和基本使用
1. 泛型的概述和基本使用: package cn.itcast_01; import java.util.ArrayList; import java.util.Iterator; /* * Arr ...
- Android(java)学习笔记92:泛型高级之通配符
package cn.itcast_07; import java.util.ArrayList; import java.util.Collection; /* * 泛型高级(通配符) * ?:任意 ...
- 【Java进阶】---map集合排序
map集合排序 这篇文章讲的不仅仅是map排序,比如把对象按某一属性排序,它都可以解决这些问题. 比如,有N个对象,每个对象有个属性就是成绩,成绩分:优秀,良好,合格.那我们如何按 ...
- java进阶学习的一些思路
搞 Java 的年薪 40W 是什么水平? - 乔戈里的回答 - 知乎 https://www.zhihu.com/question/31437847/answer/566852748 在知乎上看了他 ...
- Android(java)学习笔记31:泛型高级之通配符
1. 泛型高级之通配符: package cn.itcast_07; import java.util.ArrayList; import java.util.Collection; /* * 泛型高 ...
- Java进阶学习(3)之对象容器(下)
对象数组 对象数组中的每个元素都是对象的管理者而非对象本身 对象数组的for—each循环 集合容器(HashSet) HashSet 数学中的集合,元素间满足互异性.确定性.无序性 HashSet& ...
随机推荐
- mysql中key和index的关系
原文链接:https://blog.csdn.net/top_code/article/details/50599840
- 1. 线性DP 1143. 最长公共子序列
最经典双串: 1143. 最长公共子序列 (LCS) https://leetcode-cn.com/problems/longest-common-subsequence/submissions/ ...
- Android Support v4\v7\v13和AndroidX理解【转载】
为什么要用support库呢? 因为在低版本Android平台上开发一个APP时,想使用高版本才有的功能,此时就需要使用Support来支持兼容. 1. android-support-v4 comp ...
- 从 3.1 到 5.0 —— OpenReservation 更新记
OpenReservation 从 asp.net core 3.1 到 5.0 Intro OpenReservation 是一个开源的预约系统,最初的版本是我们学校的活动室预约系统,现在正逐步变成 ...
- mysql主备切换canal出现的问题解析
通过配置VIP,在进行主备切换时,出现的报错信息: 1.当主备节点当前binlog文件名称相同时,原主节点的position小于主备切换后的position,出现如下报错: 2020-07-02 15 ...
- 面试必看!凭借着这份 MySQL 高频面试题,我拿到了京东,字节的offer!
前言 本文主要受众为开发人员,所以不涉及到MySQL的服务部署等操作,且内容较多,大家准备好耐心和瓜子矿泉水. 前一阵系统的学习了一下MySQL,也有一些实际操作经验,偶然看到一篇和MySQL相关的面 ...
- 337. 打家劫舍 III(树上dp)
在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区.这个地区只有一个入口,我们称之为"根". 除了"根"之外,每栋房子有且只有一个" ...
- 模拟赛41 A. 四个质数的和
题目描述 给定了一个正整数 \(N\).有多少种方法将 \(N\) 分解成为四个质数 \(a,b,c,d\)的和. 例如: \(9=2+2+2+3=2+2+3+2=2+3+2+2=3+2+2+2\), ...
- Java基础教程——Java简介
Java是SUN公司1995年推出的一门高级编程语言,是一种面向Internet的编程语言,随着Java技术在Web方面的不断成熟,已经成为Web应用程序的首选开发语言. (2009年SUN公司被Or ...
- IntelliJ IDEA 配置《算法》(第四版)
红皮的算法一书,内部代码的实现调用了作者写的一个包.为了运行书内代码,需要配置相应的环境. 准备 网站:https://algs4.cs.princeton.edu/code/ 工具:IntelliJ ...