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& ...
随机推荐
- 使用 .NET 5 体验大数据和机器学习
翻译:精致码农-王亮 原文:http://dwz.win/XnM .NET 5 旨在提供统一的运行时和框架,使其在各平台都有统一的运行时行为和开发体验.微软发布了与 .NET 协作的大数据(.NET ...
- 简单STL
string: string s="5418340"; sort(s.begin(),s.end()); cout<<s; /**begin是头迭代器,end是尾迭代器 ...
- 从头学起Verilog(三):Verilog逻辑设计
引言 经过了组合逻辑和时序逻辑的复习,终于到了Verilog部分.这里主要介绍Verilog一些基础内容,包括结构化模型.TestBench编写和仿真.真值表模型. 这部分内容不多,也都十分基础,大家 ...
- Java基础 之三 继承
1.子类 1) 定义子类 //假设父类(也叫做超类)是Employee类,用extends来表示继承 public class Manager extends Employee{ //域和方法 pri ...
- ubuntu13.04修改默认启动内核
ubuntu下面的启动内核选项跟其他操作系统不一样,有个子菜单,比如我在默认的ubuntu13.04上安装了一个新的内核3.14.5,那么默认的第一项是3.14.5内核,第二项是一个子菜单,第二项里面 ...
- Python_用PyQt5 建 notepad 界面
用PyQt5建notepad界面 1 # -*-coding:utf-8 -*- 2 """ 3 简介:用PyQt5做一个对话框,有菜单(2个.有独立图标.快捷键).提示 ...
- 基于 abp vNext 微服务开发的敏捷应用构建平台 - 框架分析
总体架构 本平台从技术上采用ABP vNext和.NET Core编写的微服务架构.客户端层主要以现代浏览器为主,适配了PC端和移动端的访问,采用API和应用程序进行交互,同时提供第三方使用的 ...
- HW弹药库之红队作战手册
红方人员实战手册 声明 Author : By klion Date : 2020.2.15 寄语 : 愿 2020 后面的每一天都能一切安好 分享初衷 一来, 旨在为 "攻击" ...
- java开发两年,连Spring中bean的装配都不知道?你怎么涨薪啊
Spring 1.1.1.1 创建一个bean package com.zt.spring; public class MyBean { private String userName; privat ...
- 从执行上下文角度重新理解.NET(Core)的多线程编程[1]:基于调用链的”参数”传递
线程是操作系统能够进行运算调度的最小单位,操作系统线程进一步被封装成托管的Thread对象,手工创建并管理Thread对象已经成为了所能做到的对线程最细粒度的控制了.后来我们有了ThreadPool, ...