Java基础知识笔记(八:集合类)
目录
1 集合类简介
集合类存放于java.util包中。
集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。
集合类型主要有3种:list(集)、set(列表)和map(映射)。
具体关系如下:
Collection
List
├LinkedList
├ArrayList
└Vector
└Stack
Set
├HashSet
├TreeSet
└Linked HashSet
Map
├Hashtable
├HashMap
└WeakHashMap
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些Collection允许有相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个 Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元素
}
2 List介绍及简单使用
介绍:List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。和下面要提到的Set不同,List允许有相同的元素。
除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素, 还能向前或向后遍历。
实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。
实例:查找 List 中的最大最小值
以下实例演示了如何使用 Collections类的 max() 和 min() 方法来获取List中最大最小值:
import java.util.*;
public class Main {
public static void main(String[] args) {
List list = Arrays.asList("one Two three Four five six one three Four".split(" "));
System.out.println(list);
System.out.println("最大值: " + Collections.max(list));
System.out.println("最小值: " + Collections.min(list));
}}
以上代码运行输出结果为:
[one, Two, three, Four, five, six, one, three, Four]
最大值: three
最小值: Four
2.1 LinkedList介绍及简单使用
介绍:LinkedList类是双向列表,列表中的每个节点都包含了对前一个和后一个元素的引用.
LinkedList的构造函数如下
1. public LinkedList(): ——生成空的链表
2. public LinkedList(Collection col): 复制构造函数
实例:获取链表的第一个和最后一个元素
import java.util.LinkedList;
public class LinkedListTest{
public static void main(String[] args) {
LinkedList<String> lList = new LinkedList<String>();
lList.add("1");
lList.add("2");
lList.add("3");
lList.add("4");
lList.add("5");
System.out.println("链表的第一个元素是 : " + lList.getFirst());
System.out.println("链表最后一个元素是 : " + lList.getLast());
}
}
2.2 ArrayList介绍及简单使用
介绍:ArrayList就是传说中的动态数组,换种说法,就是Array的复杂版本,它提供了如下一些好处:
动态的增加和减少元素
实现了ICollection和IList接口
灵活的设置数组的大小
实例:
ArrayList List = new ArrayList();
for( int i=0;i <10;i++ ) //给数组增加10个Int元素
List.Add(i);
//..程序做一些处理
List.RemoveAt(5);//将第6个元素移除
for( int i=0;i <3;i++ ) //再增加3个元素
List.Add(i+20);
Int32[] values = (Int32[])List.ToArray(typeof(Int32));//返回ArrayList包含的数组
2.3 Vector介绍及简单使用
介绍:
Vector类实现了一个动态数组。和ArrayList和相似,但是两者是不同的:
Vector是同步访问的。
Vector包含了许多传统的方法,这些方法不属于集合框架。
Vector主要用在事先不知道数组的大小,或者只是需要一个可以改变大小的数组的情况。
Vector类支持4种构造方法。
第一种构造方法创建一个默认的向量,默认大小为10:
Vector()
第二种构造方法创建指定大小的向量。
Vector(int size)
第三种构造方法创建指定大小的向量,并且增量用incr指定. 增量表示向量每次增加的元素数目。
Vector(int size,int incr)
第四中构造方法创建一个包含集合c元素的向量:
Vector(Collection c)
实例:
import java.util.*;
public class VectorDemo { public static void main(String args[]) {
// initial size is 3, increment is 2
Vector v = new Vector(3, 2);
System.out.println("Initial size: " + v.size());
System.out.println("Initial capacity: " +
v.capacity());
v.addElement(new Integer(1));
v.addElement(new Integer(2));
v.addElement(new Integer(3));
v.addElement(new Integer(4));
System.out.println("Capacity after four additions: " +
v.capacity()); v.addElement(new Double(5.45));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Double(6.08));
v.addElement(new Integer(7));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Float(9.4));
v.addElement(new Integer(10));
System.out.println("Current capacity: " +
v.capacity());
v.addElement(new Integer(11));
v.addElement(new Integer(12));
System.out.println("First element: " +
(Integer)v.firstElement());
System.out.println("Last element: " +
(Integer)v.lastElement());
if(v.contains(new Integer(3)))
System.out.println("Vector contains 3.");
// enumerate the elements in the vector.
Enumeration vEnum = v.elements();
System.out.println("\nElements in vector:");
while(vEnum.hasMoreElements())
System.out.print(vEnum.nextElement() + " ");
System.out.println();
}}
以上实例编译运行结果如下:
Initial size: 0
Initial capacity: 3
Capacity after four additions: 5
Current capacity: 5
Current capacity: 7
Current capacity: 9
First element: 1Last element: 12Vector contains 3.
Elements in vector:1 2 3 4 5.45 6.08 7 9.4 10 11 12
2.3.1 Stack介绍及简单使用
介绍:
栈是Vector的一个子类,它实现了一个标准的后进先出的栈。
堆栈只定义了默认构造函数,用来创建一个空栈。 堆栈除了包括由Vector定义的所有方法,也定义了自己的一些方法。
Stack()
除了由Vector定义的所有方法,自己也定义了一些方法:
序号 |
方法描述 |
1 |
boolean empty() |
2 |
Object peek( ) |
3 |
Object pop( ) |
4 |
Object push(Object element) |
5 |
int search(Object element) |
实例:
下面的程序说明这个集合所支持的几种方法
import java.util.*;
public class StackDemo { static void showpush(Stack st, int a) {
st.push(new Integer(a));
System.out.println("push(" + a + ")");
System.out.println("stack: " + st);
} static void showpop(Stack st) {
System.out.print("pop -> ");
Integer a = (Integer) st.pop();
System.out.println(a);
System.out.println("stack: " + st);
} public static void main(String args[]) {
Stack st = new Stack();
System.out.println("stack: " + st);
showpush(st, 42);
showpush(st, 66);
showpush(st, 99);
showpop(st);
showpop(st);
showpop(st);
try {
showpop(st);
} catch (EmptyStackException e) {
System.out.println("empty stack");
}
}}
以上实例编译运行结果如下:
stack: [ ]
push(42)
stack: [42]
push(66)
stack: [42, 66]
push(99)
stack: [42, 66, 99]
pop -> 99
stack: [42, 66]
pop -> 66
stack: [42]
pop -> 42
stack: [ ]
pop -> empty stack
3 Set介绍
介绍:
Set不保存重复的元素。Set中最常被使用的是测试归属性,你可以很容易的询问某个对象是否在某个Set中。Set具有与Collection完全一样的接口,因此没有任何额外的功能。实际上Set就是Collection,只是行为不同。
实现了Set接口的主要有HashSet、TreeSet、LinkedHashSet这几个共同点就是每个相同的项只保存一份。他们也有不同点,区别如下:
3.1 HashSet介绍及简单使用
介绍:
HashSet使用的是相当复杂的方式来存储元素的,使用HashSet能够最快的获取集合中的元素,效率非常高(以空间换时间)。会根据hashcode和equals来庞端是否是同一个对象,如果hashcode一样,并且equals返回true,则是同一个对象,不能重复存放。
实例:
package com.set; import java.util.HashSet;
import java.util.Set; class Student{
int id;
public Student(int id) {
this.id = id;
}
@Override
public String toString() {
return this.id+"";
}
@Override
public int hashCode() {
return this.id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Student){
Student stu = (Student) obj;
if (stu.id == this.id)
return true;
}
return false;
}
}
public class HashSetTest {
public static void main(String[] args) {
Set<Student> set = new HashSet<Student>();
Student s1 = new Student(1);
Student s2 = new Student(1);
Student s3 = new Student(2);
set.add(s1);
set.add(s2);
set.add(s3);
for (Student s : set) {
System.out.println(s);
}
}
}
正如上例所示,重写了hashCode()和equals()方法来区分同意对象后,就不能存放同以对象了。如果注释这两个方法,则所有Student对象视为不同对象,都可以存放。
3.2 TreeSet介绍及简单使用
介绍:
TreeSet也不能存放重复对象,但是TreeSet会自动排序,如果存放的对象不能排序则会报错,所以存放的对象必须指定排序规则。排序规则包括自然排序和客户排序。
①自然排序:TreeSet要添加哪个对象就在哪个对象类上面实现java.lang.Comparable接口,并且重写comparaTo()方法,返回0则表示是同一个对象,否则为不同对象。
②客户排序:建立一个第三方类并实现java.util.Comparator接口。并重写方法。定义集合形式为TreeSet ts = new TreeSet(new 第三方类());
实例:
下面一个例子用TreeSet存放自然排序的对象:
package com.set; import java.util.Set;
import java.util.TreeSet; class Student1 implements Comparable<Student1>{
int id;
public Student1(int id) {
this.id = id;
}
@Override
public String toString() {
return this.id+"";
}
@Override
public int hashCode() {
return this.id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Student1){
Student1 stu = (Student1) obj;
if (stu.id == this.id)
return true;
}
return false;
}
public int compareTo(Student1 o) {
return (this.id-o.id);
}
} public class TreeSetTest {
public static void main(String[] args) {
Set<Student1> set = new TreeSet<Student1>();
Student1 s1 = new Student1(5);
Student1 s2 = new Student1(1);
Student1 s3 = new Student1(2);
Student1 s4 = new Student1(4);
Student1 s5 = new Student1(3);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
set.add(s5);
for (Student1 s : set) {
System.out.println(s);
}
} }
输出结果为:
1
2
3
4
5
3.3 Linked HashSet介绍
介绍:LinkedHashSet按照插入顺序保存对象,同时还保存了HashSet的查询速度。
4 Map介绍及简单使用
介绍:
Map接口中键和值一一映射. 可以通过键来获取值。
给定一个键和一个值,你可以将该值存储在一个Map对象. 之后,你可以通过键来访问对应的值。
当访问的值不存在的时候,方法就会抛出一个NoSuchElementException异常.
当对象的类型和Map里元素类型不兼容的时候,就会抛出一个 ClassCastException异常。
当在不允许使用Null对象的Map中使用Null对象,会抛出一个NullPointerException 异常。
当尝试修改一个只读的Map时,会抛出一个UnsupportedOperationException异常。
序号 |
方法描述 |
1 |
void clear( ) |
2 |
boolean containsKey(Object k) |
3 |
boolean containsValue(Object v) |
4 |
Set entrySet( ) |
5 |
boolean equals(Object obj) |
6 |
Object get(Object k) |
7 |
int hashCode( ) |
8 |
boolean isEmpty( ) |
9 |
Set keySet( ) |
10 |
Object put(Object k, Object v) |
11 |
void putAll(Map m) |
12 |
Object remove(Object k) |
13 |
int size( ) |
14 |
Collection values( ) |
实例:
import java.util.*;
public class CollectionsDemo { public static void main(String[] args) {
Map m1 = new HashMap();
m1.put("Zara", "8");
m1.put("Mahnaz", "31");
m1.put("Ayan", "12");
m1.put("Daisy", "14");
System.out.println();
System.out.println(" Map Elements");
System.out.print("\t" + m1);
}}
以上实例编译运行结果如下:
Map Elements
{Mahnaz=31, Ayan=12, Daisy=14, Zara=8}
4.1 Hashtable介绍及简单使用
介绍:
Hashtable是原始的java.util的一部分, 是一个Dictionary具体的实现 。
然而,Java 2 重构的Hashtable实现了Map接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似,但是它支持同步。
像HashMap一样,Hashtable在哈希表中存储键/值对。当使用一个哈希表,要指定用作键的对象,以及要链接到该键的值。
然后,该键经过哈希处理,所得到的散列码被用作存储在该表中值的索引。
实例:
下面的程序说明这个数据结构支持的几个方法:
import java.util.*;
public class HashTableDemo { public static void main(String args[]) {
// Create a hash map
Hashtable balance = new Hashtable();
Enumeration names;
String str;
double bal; balance.put("Zara", new Double(3434.34));
balance.put("Mahnaz", new Double(123.22));
balance.put("Ayan", new Double(1378.00));
balance.put("Daisy", new Double(99.22));
balance.put("Qadir", new Double(-19.08)); // Show all balances in hash table.
names = balance.keys();
while(names.hasMoreElements()) {
str = (String) names.nextElement();
System.out.println(str + ": " +
balance.get(str));
}
System.out.println();
// Deposit 1,000 into Zara's account
bal = ((Double)balance.get("Zara")).doubleValue();
balance.put("Zara", new Double(bal+1000));
System.out.println("Zara's new balance: " +
balance.get("Zara"));
}}
以上实例编译运行结果如下:
Qadir: -19.08Zara: 3434.34Mahnaz: 123.22Daisy: 99.22Ayan: 1378.0
Zara's new balance: 4434.34
4.2 HashMap简单使用
介绍:以下实例演示了如何使用 Collection 类的 iterator() 方法来遍历集合:
import java.util.*;
public class Main {
public static void main(String[] args) {
HashMap< String, String> hMap =
new HashMap< String, String>();
hMap.put("1", "1st");
hMap.put("2", "2nd");
hMap.put("3", "3rd");
Collection cl = hMap.values();
Iterator itr = cl.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
}}
以上代码运行输出结果为:
3rd
2nd
1st
4.3 WeakHashMap介绍
介绍:
WeakHashMap实现了Map接口,是HashMap的一种实现,他使用弱引用作为内部数据的存储方案,WeakHashMap可以作为简单缓存表的解决方案,当系统内存不够的时候,垃圾收集器会自动的清除没有在其他任何地方被引用的键值对。
如果需要用一张很大的HashMap作为缓存表,那么可以考虑使用WeakHashMap,当键值不存在的时候添加到表中,存在即取出其值。
WeakHashMap weakMap = new WeakHashMap<Integer, byte[]>(); for(int i = 0; i < 10000; i++){ Integer ii = new Integer(i); weakMap.put(ii, new byte[i]); }
参考资料:
Java基础知识笔记(八:集合类)的更多相关文章
- java基础知识-笔记整理
1.查看已安装jdk文件路径 CMD输入java -verbose. 2.java学习提升路线 java学习视屏地址: http://www.icoolxue.com/album/show/38 ...
- Java基础知识笔记(四:多线程基础及生命周期)
一.多线程基础 编写线程程序主要是构造线程类.构造线程类的方式主要有两种,一种是通过构造类java.lang.Thread的子类,另一种是通过构造方法实现接口java.lang.Runnable的类. ...
- Java基础知识笔记(一:修饰词、向量、哈希表)
一.Java语言的特点(养成经常查看Java在线帮助文档的习惯) (1)简单性:Java语言是在C和C++计算机语言的基础上进行简化和改进的一种新型计算机语言.它去掉了C和C++最难正确应用的指针和最 ...
- Java基础学习笔记八 Java基础语法之接口和多态
接口 接口概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”.接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义 ...
- JAVA基础知识笔记
1.类只能用Public修饰,不能使用protected.private修饰.也可以不加修饰符,称做友好类. 2.类的实体元素包含成员变量和方法的定义,成员变量分为实例变量和类变量(static修饰的 ...
- Java基础知识笔记第二章:基本数据类型与数组
标识符和关键字 标识符: 1:字母,数字,下划线,美元符号 2.不能以数字开头 3.标识符不能是:true false null(尽管true false null不是java的关键字 ...
- Java基础知识笔记(五:多线程的同步问题)
编写多线程程序往往是为了提高资源的利用率,或者提高程序的运行效率,或者更好地监控程序的运行过程等.多线程同步处理的目的是为了让多个线程协调地并发工作.对多线程进行同步处理可以通过同步方法和同步语句块实 ...
- Java基础知识笔记(六:网络程序设计)
一.统一资源定位地址(URL) (1)网络地址 在网络上,计算机是通过网络地址标识.网络地址通常有两种表示方法,第一种表示方法通常采用4个整数组成,例如: 166.111.4.100表示某一网站服务器 ...
- Java基础知识笔记(七:接口、变量作用域和参数传递)
一.接口 Java语言不允许一个子类拥有多个直接父类,即任何子类只能有一个直接父类.但允许一个类实现多个接口,即在定义类的接口名称列表中可以包含1个或多个接口名称,从而实现多重继承的特性.接口的定义格 ...
随机推荐
- Java线上应用故障排查之一:高CPU占用
一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. 以我们最近出现的一个实际故障为例,介绍怎么定位和解决这类问题. 根据top命令,发现PID为28555的Java进程占 ...
- LINQ系列目录
1. LINQ准备 1.1 C#中与LINQ相关特性 2. LINQ to Object 2.1 LINQ to Object投影操作符(Select/SelectMany/Let) 2.2 LINQ ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(36)-文章发布系统③-kindeditor使用
系列目录 我相信目前国内富文本编辑器中KindEditor 属于前列,详细的中文帮助文档,简单的加载方式,可以定制的轻量级.都是系统的首选 很多文章教程有kindeditor的使用,但本文比较特别可能 ...
- 【CSS进阶】CSS 颜色体系详解
说到 CSS 颜色,相比大家都不会陌生,本文是我个人对 CSS 颜色体系的一个系统总结与学习,分享给大家. 先用一张图直观的感受一下与 CSS 颜色相关大概覆盖了哪些内容. 接下来的行文内容大概会按照 ...
- SQLServer:什么是主键(PK)和外键(FK)?
一.主键与外键 1.主键是用来唯一地标识一行数据.主键列必须包含唯一的值,且不能包含空值(null). 2.主键可以建立在每张二维表中单列或者多列上. 3.一张二维表上的外键可以引用另一张二维表上对应 ...
- 初步认识Node 之Express
通过本文,你会对Express有一个较为具体的了解. 起源 2009年6月26日,TJ Holowaychuk提交了Express的第一次commit,接下来在2010年1月2日,有660次co ...
- wordpress插件bug排查后记(记一次由于开启memecached引起的插件bug)
这篇文章是写给自己的. 周三的时候我在维护公司的一个wordpress项目页面时发现了一个非常奇怪的情况:当我尝试更新网站上的一个页面后,在wordpress后台的编辑器中发现其内容并没有按我预期的将 ...
- 跨域之Ajax
提到Ajax,一般都会想到XMLHttpRequest对象,通过这个对象向服务器发送请求,可以实现页面无刷新而更新数据. 由于同源策略的限制,一般情况下,只能通过XMLHttpRequest对象向同源 ...
- 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍
一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...
- Both must set "document.domain" to the same value to allow access.
有两个域名指向我的网站,其中一个域名访问我的网站的话就可以看到日期控件 另一个域名访问我的网站不能看到日期控件, 在EF中使用日期控件,浏览器审查元素后看到,报这个错误“Both must set & ...