文章目录
一、数据结构
Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类:
1.枚举(Enumeration)
枚举接口虽然它本身不属于数据结构,但它在其他数据结构的范畴里应用很广。 枚举接口定义了一种从数据结构中取回连续元素的方式。
常用方法:
- boolean hasMoreElements( )
测试此枚举是否包含更多的元素。 - Object nextElement( )
如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
import java.util.Vector;
import java.util.Enumeration;
public class EnumerationTester {
public static void main(String args[]) {
Enumeration<String> days;
Vector<String> dayNames = new Vector<String>();
dayNames.add("Sunday");
dayNames.add("Monday");
dayNames.add("Tuesday");
dayNames.add("Wednesday");
dayNames.add("Thursday");
dayNames.add("Friday");
dayNames.add("Saturday");
days = dayNames.elements();
while (days.hasMoreElements()){
System.out.println(days.nextElement());
}
}
}
2.位集合(BitSet)
位集合类实现了一组可以单独设置和清除的位或标志。
该类在处理一组布尔值的时候非常有用,你只需要给每个值赋值一"位",然后对位进行适当的设置或清除,就可以对布尔值进行操作了。
3.向量(Vector)
向量(Vector)类和传统数组非常相似,使用Vector类最主要的好处就是在创建对象的时候不必给对象指定大小,它的大小会根据需要动态的变化。
①. vector和ArrayList区别:
- Vector 是同步访问的。
- Vector 包含了许多传统的方法,这些方法不属于集合框架。
②. 构造:
Vector() // 默认向量,大小为10
Vector(int size) //构造指定大小的向量
Vector(int size,int incr) //指定空间不够时向量空间的增量
Vector(Collection c) //创建一个包含集合 c 元素的向量
4.栈(Stack)
栈(Stack)实现了一个后进先出(LIFO)的数据结构。
5.字典(Dictionary)
Dictionary 类是一个抽象类,用来存储键/值对,作用和Map类相似。
给出键和值,你就可以将值存储在Dictionary对象中。一旦该值被存储,就可以通过它的键来获取它。所以和Map一样, Dictionary 也可以作为一个键/值对列表。
早已被Map接口替代。
6.哈希表(Hashtable)
Hashtable是原始的java.util的一部分, 是一个Dictionary具体的实现 。
然而,Java 2 重构的Hashtable实现了Map接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似,但是它支持同步。
①. 概念:
Hashtable在哈希表中存储键/值对。当使用一个哈希表,要指定用作键的对象,以及要链接到该键的值。
然后,该键经过哈希处理,所得到的散列码被用作存储在该表中值的索引。
②. 构造:
Hashtable()
Hashtable(int size)
Hashtable(int size,float fillRatio) //创建了一个指定大小的哈希表,并且通过fillRatio指定填充比例。
Hashtable(Map m) //哈希表的容量被设置为M的两倍。
7.属性(Properties)
Properties 继承于 Hashtable。表示一个持久的属性集.属性列表中每个键及其对应值都是一个字符串。
集合框架
Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。
Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。
Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包。
二 .ArrayList
1.概念
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
2. 语法
import java.util.ArrayList; // 引入 ArrayList 类
ArrayList<E> objectName =new ArrayList<>(); // 初始化
E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
ArrayList 中的元素实际上是对象,如果我们要存储其他类型,而 只能为引用数据类型,这时我们就需要使用到基本类型的包装类。
基本类型 | 引用类型 |
---|---|
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
3.操作
①. 添加元素: add(element)
②. 访问元素: get( index)
③. 修改元素: set(index, value)
④. 删除元素: remove(index)
⑤. 计算大小: size()
⑥. 迭代数组:
ArrayList<String> sites = new ArrayList<String>();
for (int i = 0; i < sites.size(); i++) { //一般for循环,
System.out.println(sites.get(i));
}
for (String i : sites) { //增强型for循环
System.out.println(i);
}
三、LinkedList
1.概念
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
链表可分为单向链表和双向链表。
2.语法
// 引入 LinkedList 类
import java.util.LinkedList;
LinkedList<E> list = new LinkedList<E>(); // 普通创建方法
3.操作
①. 添加元素: add(尾部添加) addFirst(头部添加元素) addLast(尾部添加元素)
②. 访问元素: getLast()
③. 修改元素: set(index, value)
④. 删除元素: removeFirst(移除头部) removeLast(移除尾部)
⑤. 计算大小: size()
四、HashSet
1.概念
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。HashSet 是无序的,即不会记录插入的顺序。
HashSet 允许有 null 值。
HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
2.语法
import java.util.HashSet; // 引入 HashSet 类
HashSet<String> sites = new HashSet<String>();
3. 操作
①. 添加元素: add(element)
②. 元素是否存在: contains(element)
③. 删除元素: remove(index)
④. 计算大小: size()
五、HashMap
1.概念
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。HashMap 是无序的,即不会记录插入的顺序。
HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
2.语法
import java.util.HashMap; // 引入 HashMap 类
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
3.操作
①. 添加键值对: put(key,value)
②.访问元素: get(key)
③. 删除元素: remove(key)
④. 大小 size()
⑤.迭代:
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
// 输出 key 和 value
for (Integer i : Sites.keySet()) {
System.out.println("key: " + i + " value: " + Sites.get(i));
}
// 返回所有 value 值
for(String value: Sites.values()) {
// 输出每一个value
System.out.print(value + ", ");
}
六、Iterator(迭代器)
1.概念
Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。
Iterator 是 Java 迭代器最简单的实现
2.操作
迭代器 it 的两个基本操作是 next 、hasNext 和 remove。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素。
调用 it.remove() 将迭代器返回的元素删除。
3.代码演示
import java.util.Iterator;
import java.util.ArrayList
ArrayList<String> sites=new ArrayList<String>();
//获取迭代器
Iterator<String> it=sites.iterator();
//循环集合元素
while(it.hasNext()){
System.out.println(it.next());
}
七、Java泛型
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
1.泛型方法
该方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。
①. 定义泛型方法的规则
- 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前。
- 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
- 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
- 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int、double、char 等)。
②. 泛型标记符:
- E - Element (在集合中使用,因为集合中存放的是元素)
- T - Type(Java 类)
- K - Key(键)
- V - Value(值)
- N - Number(数值类型)
- ? - 表示不确定的 java 类型
③.示例
打印不同类型的数组元素
public class GenericMethodTest
{
// 泛型方法 printArray
public static < E > void printArray( E[] inputArray )
{
// 输出数组元素
for ( E element : inputArray ){
System.out.printf( "%s ", element );
}
System.out.println();
}
public static void main( String args[] )
{
// 创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
System.out.println( "整型数组元素为:" );
printArray( intArray ); // 传递一个整型数组
System.out.println( "\n双精度型数组元素为:" );
printArray( doubleArray ); // 传递一个双精度型数组
System.out.println( "\n字符型数组元素为:" );
printArray( charArray ); // 传递一个字符型数组
}
}
2. 泛型类
泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。
public class Box<T> {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
Box<String> stringBox = new Box<String>();
integerBox.add(new Integer(10));
stringBox.add(new String("菜鸟教程"));
System.out.printf("整型值为 :%d\n\n", integerBox.get());
System.out.printf("字符串为 :%s\n", stringBox.get());
}
}
3.类型通配符
①. 类型通配符一般是使用 ? 代替具体的类型参数。例如 List<?> 在逻辑上是 List<String>,List<Integer> 等所有 List<具体类型实参> 的父类。
import java.util.*;
public class GenericTest {
public static void main(String[] args) {
List<String> name = new ArrayList<String>();
List<Integer> age = new ArrayList<Integer>();
List<Number> number = new ArrayList<Number>();
name.add("icon");
age.add(18);
number.add(314);
getData(name);
getData(age);
getData(number);
}
public static void getData(List<?> data) {
System.out.println("data :" + data.get(0));
}
}
②. 类型通配符上限通过形如List来定义,如此定义就是通配符泛型值接受Number及其下层子类类型。
import java.util.*;
public class GenericTest {
public static void main(String[] args) {
List<String> name = new ArrayList<String>();
List<Integer> age = new ArrayList<Integer>();
List<Number> number = new ArrayList<Number>();
name.add("icon");
age.add(18);
number.add(314);
//getUperNumber(name);//1 ,或报错,规定了参数泛型上限为Number
getUperNumber(age);//2
getUperNumber(number);//3
}
public static void getData(List<?> data) {
System.out.println("data :" + data.get(0));
}
public static void getUperNumber(List<? extends Number> data) {
System.out.println("data :" + data.get(0));
}
}