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& ...
随机推荐
- /etc/resolv.conf文件自动恢复的解决方法
/etc/resolv.conf文件自动恢复的解决方法: service NetworkManager stop #后台进程关闭 chkconfig NetworkManager off #配置关闭, ...
- 怎样禁止Ceph OSD的自动挂载
前言 本篇来源于群里一个人的问题,有没有办法让ceph的磁盘不自动挂载,一般人的问题都是怎样让ceph能够自动挂载,在centos 7 平台下 ceph jewel版本以后都是有自动挂载的处理的,这个 ...
- Dance Dance Revolution
今天我们来讲 Dance Dance Revolution这题 本题原网址 注意本题为多组输入输出,直到输入单个零而止(题面有点小问题) 很明显,此题为一道动态规划题(请不要妄想用贪心算法过这题,尽管 ...
- SNMP介绍及使用,超有用,建议收藏!
写在前面 如果你是对SNMP完全不了解,或者只想学习如何使用现成的SNMP工具,那你找对了文章,但如果你希望学习SNMP具体协议内容,推荐阅读官方的RFC文档. 1. 简介 SNMP(Simple N ...
- webug第二关:从图片中你能找到什么?
第二关:从图片中你能找到什么? 记事本打开发现提示 binwalk,发现压缩包rar
- vue中使用transition和animate.css动画效果
一.单个动画中,使用div中引用animate动画 1.下载依赖 npm install animate.css –save 2.main.js中全局引用 import animate from 'a ...
- TCP的ACK机制
下面是整个的tcp的三次握手和四次挥手的协议 TCP四次挥手 在客户端先发送一个FIN的包,表示要close(),客户端想和连接断开,发完之后出于FIN_WAIT_1状态下:服务端收到之后就变成CLO ...
- jQuery 第五章 实例方法 事件
.on() .one() .off() .trigger() .click / keydown / mouseenter ... .hover() ----------------------- ...
- Nacos安装与启动教程
前言 Nacos是阿里巴巴集团开源的一个易于使用的平台,专为动态服务发现,配置和服务管理而设计,Nacos基本上支持现在所有类型的服务,例如,Dubbo / gRPC服务,Spring Cloud R ...
- 简单好用的TCP/UDP高并发性能测试工具
工具下载地址: 链接:https://pan.baidu.com/s/1fJ6Kz-mfFu_RANrgKqYiyA 提取码:0pyf 最近测试智能设备的远程的性能,思路主要是通过UDP对IP和端口发 ...