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& ...
随机推荐
- 5Flask数据库
video 43 安装mysql video44 SQLALchemy连接
- ClassNotFoundException: java.util.ArrayList$SubList 错误
ClassNotFoundException: java.util.ArrayList$SubListjava.lang.RuntimeException: java.lang.ClassNotFou ...
- nginx&http 第三章 ngx http ngx_http_process_request_line读取和处理HTTP头部的行
在 ngx_http_wait_request_handler 的最后调用了 ngx_http_process_request_line 函数用来处理和解析这次请求的全文 在读事件被触发时,内核套接字 ...
- Kafka 消费者及消费者分区策略
消费方式: consumer 采用 pull(拉)模式从 broker 中读取数据. push(推)模式很难适应消费速率不同的消费者,因为消息发送速率是由 broker 决定的. 它的目标是尽可能以最 ...
- 这才是图文并茂:我写了1万多字,就是为了让你了解AQS是怎么运行的
前言 如果你想深入研究Java并发的话,那么AQS一定是绕不开的一块知识点,Java并发包很多的同步工具类底层都是基于AQS来实现的,比如我们工作中经常用的Lock工具ReentrantLock.栅栏 ...
- 15 张图, 把TCP/IP 讲得一清二楚!
一.TCP/IP模型 TCP/IP协议模型(Transmission Control Protocol/Internet Protocol),包含了一系列构成互联网基础的网络协议,是Interne ...
- php插入一百万测试数据(实例)
<?phpset_time_limit(0);function a(){ header("Content-Type:text/html;charset=utf-8"); $s ...
- Android应用测试指南
一.Android 的 SDK Windows 版本安装 按顺序安装以下内容 1. 安装JDK(Java Development Kit, 即Java开发工具包) 2. 安装Eclipse 集成 ...
- redis cluster下的pipeline
因为key在cluster分布在不同的slot,可能在不同的机器,部分redis的客户端(比如jedis)是不支持pipeline的 针对jedis我们可能要先把这些key对应的slot手机起来,得到 ...
- LeetCode 029 Divide Two Integers
题目要求:Divide Two Integers Divide two integers without using multiplication, division and mod operator ...