泛型:
数组就是一种容器,可以在其中放置对象或基本类型数据.
数组的优势:是一种简单的线性序列,可以快速地访问数组元素,效率高.如果从效率和类型检查的角度讲,
数组是最好的.
数组的劣势:不灵活.容量需要事先定义好,不能随着需求的变化而扩容.
以下是容器的接口层次结构图:
-----------------------------------------
Collection Map
^ ^
/ \ |
/ \ HashMap
/ \
Set List
/ |
/ / \
HashSet / \
ArrayList LinkedList
-----------------------------------------
泛型是JDK1.5以后增加的,它可以帮助我们建立类型安全的集合.在使用了泛型的集合中,遍历时不必进行强制类型转换.
JDK提供了支持泛型的编译器,将运行时的类型检查提前到了编译时执行,提高了代码可读性和安全性.
泛型的本质就是“数据类型的参数化”. 我们可以把“泛型”理解为数据类型的一个占位符(形式参数),即告诉编译器,
在调用泛型时必须传入实际类型.
-----------------------------------------
自定义泛型:
我们可以在类的声明处增加泛型列表,如:<T,E,V>.
此处,字符可以是任何标识符,一般采用这3个字母.
----------------------------------------
public class TestGeneric {
public static void main(String[] args) {
MyCollection<String> mm = new MyCollection<String>();
mm.set("字符串", 0);
String str = mm.get(0);
}
}
class MyCollection<E>{
Object[] obj = new Object[6];
public void set(E e,int index) {
obj[index] = e;
}
public E get(int index) {
return (E)obj[index];
}
}
----------------------------------------
容器中使用泛型:
容器相关类都定义了泛型,我们在开发和工作中,在使用容器类时都要使用泛型.这样,在容器的存储数据、
读取数据时都避免了大量的类型判断,非常便捷.
----------------------------------
public class Test {
public static void main(String[] args) {
// 以下代码中List、Set、Map、Iterator都是与容器相关的接口;
List<String> list = new ArrayList<String>();
Set<Man> mans = new HashSet<Man>();
Map<Integer, Man> maps = new HashMap<Integer, Man>();
Iterator<Man> iterator = mans.iterator();
}
}
-----------------------------------
Collection、List、Set、Map、Iterator接口都定义了泛型.
Collection接口:
Collection 表示一组对象.Collection接口的两个子接口是List、Set接口.
-----------------------------------
方法 说明
boolean add(Object element) 增加元素到容器中
boolean remove(Object element) 从容器中移除元素
boolean contains(Object element) 容器中是否包含该元素
int size() 容器中元素的数量
boolean isEmpty() 容器是否为空
void clear() 清空容器中所有元素
Iterator iterator() 获得迭代器,用于遍历所有元素
boolean containsAll(Collection c) 本容器是否包含c容器中的所有元素
boolean addAll(Collection c) 将容器c中所有元素增加到本容器
boolean removeAll(Collection c) 移除本容器和容器c中都包含的元素
boolean retainAll(Collection c) 取本容器和容器c中都包含的元素,移除非交集元素.
Object[] toArray() 转化成Object数组
-----------------------------------
由于List、Set是Collection的子接口,意味着所有List、Set的实现类都有上面的方法.
List特点和常用方法:
List是有序、可重复的容器.
有序:List中每个元素都有索引标记.可以根据元素的索引标记(在List中的位置)访问元素,从而精确控制这些元素.
可重复:List允许加入重复的元素.更确切地讲,List通常允许满足 e1.equals(e2) 的元素重复加入容器.
除了Collection接口中的方法,List多了一些跟顺序(索引)有关的方法:
-----------------------------------
方法 说明
void add(int index,Object element) 在指定位置插入元素,以前元素全部后移一位
Object set(int index,Object element) 修改指定位置的元素
Object get(int index) 返回指定位置的元素
Object remove(intindex) 删除指定位置的元素,后面元素全部前移一位
int indexOf(Object o) 返回第一个匹配元素的索引,如果没有该元素,返回-1.
int lastIndexOf(Object o) 返回最后一个匹配元素的索引,如果没有该元素,返回-1.
-----------------------------------
List接口常用的实现类有3个:ArrayList、LinkedList和Vector.
-----------------------------------
例:
import java.util.ArrayList;
import java.util.Collection;
public class TestList {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
System.out.println(c.size());
System.out.println(c.isEmpty()); // 判断容器中是否为空
// 向容器中添加元素
c.add("dog");
c.add("cat");
System.out.println(c.contains("dog")); // 判断容器中是否包含此元素
System.out.println(c);
System.out.println(c.size()); // 容器中元素的个数
Object[] obj = c.toArray(); // 将容器转换成对象数组
System.out.println(obj);
c.remove("cat"); // 从容器中移除某元素
System.out.println(c);
c.clear(); // 移除容器中的所有元素
System.out.println(c);
}
}
-----------------------------------
两个List之间的元素操作:
import java.util.*;
public class TestList02 {
public static void main(String[] args) {
List<String> c1 = new ArrayList<>();
c1.add("aaa");
c1.add("bbb");
c1.add("ccc");
List<String> c2 = new ArrayList<>();
c2.add("bbb");
c2.add("ddd");
c2.add("eee");
System.out.println("List01:"+c1);
System.out.println("List02:"+c2);
c1.addAll(c2); // 将c2中所有元素都加入到c1中
boolean b = c1.containsAll(c2); // 判断c1中是否包含c2的所有元素
c1.removeAll(c2); // 将c2中在c1中出现的所有元素都删除(删除交集元素)
c1.retainAll(c2); // 取交集
System.out.println("List01:"+c1);
System.out.print(b);
}
}
List中操作索引的常用方法:
import java.util.*;
public class Test03 {
public static void main(String[] args) {
List<String> c = new ArrayList<>();
c.add("A");
c.add("B");
c.add("C");
c.add("D");
System.out.println(c);
c.add(1, "X"); // 在指定位置插入元素
System.out.println(c);
c.remove(2); // 删除指定位置的元素
System.out.println(c);
c.set(2,"MMM"); // 将指定位置设置为指定元素
System.out.println(c);
System.out.println(c.get(1)); // 获取指定索引位置的元素
c.add("D");
c.add("C");
c.add("B");
c.add("A");
System.out.println(c);
System.out.println(c.indexOf("D")); // 获取元素第一次出现的位置索引,没有则返回-1
System.out.println(c.lastIndexOf("A")); // 获取元素最后一次出现的位置索引
}
}
手动实现容器ArrayList:
ArrayList底层是用数组实现的存储. 特点:查询效率高,增删效率低,线程不安全.我们一般使用它.
--------------------------------
public class MyCollection<E> {
private Object[] elementData;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public MyCollection() {
elementData = new Object[DEFAULT_CAPACITY];
}
public int size() {
return size;
}
public boolean isEmpty() {
if(size==0) {
return true;
}
return false;
}
public MyCollection(int capacity) {
if(capacity < 0) {
throw new RuntimeException("索引不能为负数");
}else if(capacity == 0){
elementData = new Object[DEFAULT_CAPACITY];
}
elementData = new Object[capacity];
}
// 添加元素
public void add(E element) {
if(size==elementData.length) {
// 对容器扩容
Object[] newArray = new Object[elementData.length+(elementData.length >> 1)];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
this.elementData = newArray;
}
elementData[size++] = element;
}
// 重写toString方法,打印所有元素
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("[");
for(int i=0;i<size;i++) {
str.append(elementData[i]+", ");
}
str.setCharAt(str.length()-2, ']');
str.delete(str.length()-1, str.length());
return str.toString();
}
// 获取指定位置元素
public E get(int index) {
checkRange(index);
return (E)elementData[index];
}
// 设置指定位置的元素
public void set(int index, E element) {
checkRange(index);
elementData[index] = element;
}
// 检查是否越界
public void checkRange(int index) {
if(index<0||index>size-1) {
throw new RuntimeException("索引错误");
}
}
// 删除指定元素
public void remove(E element) {
for(int i=0;i<size;i++) {
if(elementData[i].equals(element)) {
remove(i);
}
}
}
public void remove(int index) {
checkRange(index);
if(index!=size-1) {
// 移动的长度
int moveLen = size-index-1;
System.arraycopy(elementData, index+1, elementData, index, moveLen);
}
elementData[--size] = null; // 最后位置的索引为size-1,所以应该先减一
}
public static void main(String[] args) {
MyCollection<String> arr = new MyCollection<>(20);
for(int i=0;i<50;i++) {
arr.add("dog:"+i);
}
System.out.println(arr);
arr.set(10, "cat");
String s = arr.get(10);
System.out.println(s);
System.out.println(arr);
arr.remove(3);
System.out.println(arr);
arr.remove("dog:8");
System.out.println(arr);
System.out.println(arr.size());
System.out.println(arr.isEmpty());
}
}
手动实现容器LinkedList:
LinkedList底层用双向链表实现的存储.特点:查询效率低,增删效率高,线程不安全.
双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向前一个节点和后一个节点.
所以,从双向链表中的任意一个节点开始,都可以很方便地找到所有节点.
------------------------------------
public class Node {
Node previous;
Node next;
Object element;
public Node(Node previous, Node next, Object element) {
super();
this.previous = previous;
this.next = next;
this.element = element;
}
public Node(Object element) {
super();
this.element = element;
}
}
------------------------------------
public class LinkedList<E>{
private Node first;
private Node last;
private static int size;
// 在指定位置插入元素
public void add(int index,E element) {
Node temp = getNode(index);
Node newNode = new Node(element);
if(temp!=null) {
Node up = temp.previous;
Node down = temp.next;
if(up!=null) {
up.next = newNode;
newNode.previous = up;
}else {
first = newNode;
}
newNode.next = temp;
temp.previous = newNode;
}
size++;
}
// 删除指定位置元素
public void remove(int index) {
Node temp = getNode(index);
Node down;
Node up;
if(temp!=null) {
down = temp.next;
up = temp.previous;
if(up!=null) {
up.next = down;
}else {
first = down;
}
if(down!=null) {
down.previous = up;
}else {
last=up;
}
}
size--;
}
// 获取指定位置节点元素的值
public E get(int index) {
Node temp = getNode(index);
return temp!=null ? (E)temp.element:null;
}
private void checkRange(int index) {
if(index<0||index>size-1) {
throw new RuntimeException("索引数字不合法:"+index);
}
}
// 获取指定索引位置节点
private Node getNode(int index) {
checkRange(index);
Node temp = null;
if(index<(size>>1)) {
temp = first;
for(int i=0;i<index;i++) {
temp = temp.next;
}
}else {
temp = last;
for(int i=size-1;i>index;i--) {
temp = temp.previous;
}
}
return temp;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder("[");
Node temp = first;
while(temp!=null) {
str.append(temp.element+", ");
temp = temp.next;
}
str.setCharAt(str.length()-2, ']');
str.delete(str.length()-1, str.length());
System.out.println(str);
return "";
}
// 增加节点
public void add(E element) {
Node node = new Node(element);
if(first==null) {
first = node;
last = node;
}else {
node.previous = last;
node.next = null;
last.next = node;
last = node;
}
size++;
}
public static int size() {
return size;
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
list.add("b");
list.add("c");
list.toString();
System.out.println(list.get(2));
list.remove(5);
list.toString();
list.add(0, "123");
list.toString();
list.add(2,"222");
list.toString();
list.add(list.size()-1,"00");
list.toString();
}
}
Vector向量:
Vector底层是用数组实现的List,相关的方法都加了同步检查,因此“线程安全,效率低”.很多方法增加了synchronized同步标记.
1. 涉及线程安全时,用Vector.
2. 不存在线程安全问题时,并且查找较多用ArrayList.
3. 不存在线程安全问题时,增加或删除元素较多用LinkedList.
Map接口:
Map就是用来存储“键(key)-值(value) 对”的. Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复.
Map 接口的实现类有HashMap、TreeMap、HashTable、Properties等.
---------------------------------------
Map接口中常用的方法
方法 说明
Object put(Object key, Object value) 存放键值对
Object get(Object key) 通过键对象查找得到值对象
Object remove(Object key) 删除键对象对应的键值对
boolean containsKey(Object key) Map容器中是否包含键对象对应的键值对
boolean containsValue(Object value) Map容器中是否包含值对象对应的键值对
int size() 包含键值对的数量
boolean isEmpty() Map是否为空
void putAll(Map t) 将的所有键值对存放到本map对象
void clear() 清空本map对象所有键值对
---------------------------------------
HashMap和HashTable:
HashMap采用哈希算法实现,是Map接口最常用的实现类. 由于底层采用了哈希表存储数据,我们要求键不能重复,
如果发生重复,新的键值对会替换旧的键值对. HashMap在查找、删除、修改方面都有非常高的效率.
HashTable类和HashMap用法几乎一样,底层实现几乎一样,只不过HashTable的方法添加了synchronized关键字确保线程同步检查,效率较低.
HashMap与HashTable的区别:
1. HashMap: 线程不安全,效率高.允许key或value为null.
2. HashTable: 线程安全,效率低.不允许key或value为null.
---------------------------------------
例一:
import java.util.HashMap;
import java.util.Map;
public class TestMap {
public static void main(String[] args) {
Map<Integer,String> m1 = new HashMap<>();
m1.put(1, "a");
m1.put(2, "b");
m1.put(3, "c");
System.out.println(m1.get(1));
System.out.println(m1.size());
System.out.println(m1.isEmpty());
System.out.println(m1.containsKey(2));
System.out.println(m1.containsValue("c"));
Map<Integer,String> m2 = new HashMap<>();
m2.put(4, "++");
m2.put(5, "**");
m1.putAll(m2);
System.out.println(m1);
// 重复键时(根据equals方法判断),前面键对应的值会被覆盖
m1.put(3, "三");
System.out.println(m1);
}
}
---------------------------------------
例二:
import java.util.HashMap;
import java.util.Map;
public class TestMap2 {
public static void main(String[] args) {
Map<Integer,Employee> em1 = new HashMap<>();
Employee e1 = new Employee(10001, "张一", 3211.11);
Employee e2 = new Employee(10002, "张二", 123);
Employee e3 = new Employee(10003, "张三", 2367.64);
Employee e4 = new Employee(10001, "张四", 1022);
em1.put(10001, e1);
em1.put(10002, e2);
em1.put(10002, e2);
em1.get(10001).toString();
em1.put(10001, e4);
em1.get(10001).toString();
}
}
class Employee{
private int id;
private String ename;
private double salary;
public Employee(int id, String ename, double salary) {
super();
this.id = id;
this.ename = ename;
this.salary = salary;
}
@Override
public String toString() {
System.out.println("id:" + id + " name:"+ename);
return super.toString();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
---------------------------------------
手动实现HashMap基础功能:
---------------------------------------
public class Node2<K,V>{
int hash;
K key;
V value;
Node2 next;
}
---------------------------------------
public class TestHashMap<K,V> {
Node2[] table; // 位桶数组,bucket array
int size; // 存放的键值对的个数
public TestHashMap() {
table = new Node2[16]; // 长度一般定义成2的整数幂
}
public void put(K key, V value) {
// 定义新的节点
Node2 newNode = new Node2();
newNode.hash = myHash(key.hashCode(),table.length);
newNode.key = key;
newNode.value = value;
newNode.next = null;
// 取出hash值对应的那个数组位置的初节点
Node2 temp = table[newNode.hash];
Node2 iterLast = null; // 正在遍历的最后一个元素
boolean keyRepeat = false;
if(temp==null) {
// 此处数组元素为空,直接将新节点放进去
table[newNode.hash] = newNode;
size++;
}else {
// 此处数组不为空,遍历对应的链表
while(temp!=null) {
// 判断key如果重复,则覆盖
if(temp.key.equals(key)) {
keyRepeat = true;
temp.value = value; // 更新键对应的值
break;
}else {
// key不重复,则遍历下一个
iterLast = temp;
temp = temp.next;
}
}
if(!keyRepeat) {
// 如果没有发生key重复的情况,则添加到链表最后
iterLast.next = newNode;
size++;
}
}
}
public V get(K key) {
int hash = myHash(key.hashCode(),table.length);
V value = null;
if(table[hash]!=null) {
Node2 temp = table[hash];
while(temp!=null) {
if(temp.key.equals(key)) {
value = (V)temp.value;
break;
}else {
temp = temp.next;
}
}
}
return value;
}
public int myHash(int v,int length) {
// System.out.println("hash in myHash:"+(v&(length-1))); // 直接位运算,效率高
// System.out.println("hash in myHash:"+(v%(length-1))); // 取模运算,效率低
return v&(length-1);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
// 遍历bucket数组
for(int i=0;i<table.length;i++) {
Node2 temp = table[i];
// 遍历链表
while(temp!=null) {
sb.append(temp.key+":"+temp.value+", ");
temp = temp.next;
}
}
sb.setCharAt(sb.length()-2, '}');
sb.deleteCharAt(sb.length()-1);
System.out.println(sb);
return super.toString();
}
public static void main(String[] args) {
TestHashMap<Integer,String> m = new TestHashMap<>();
m.put(10, "aa");
m.put(20, "bb");
m.put(30, "cc");
m.put(20, "adawd");
m.put(53, "ee");
m.put(69, "tt");
m.put(85, "oo");
System.out.println(m);
System.out.println(m.get(30));
}
}
---------------------------------------
TreeMap的使用和Comparable接口的使用:
TreeMap是红黑二叉树的典型实现.我们打开TreeMap的源码,发现里面有一行核心代码:
private transient Entry<K,V> root = null;
Entry(是TreeMap的内部类)里面存储了本身数据、左节点、右节点、父节点、以及节点颜色. TreeMap的put()/remove()方法大量使用了红黑树的理论.
TreeMap和HashMap实现了同样的接口Map,因此,用法对于调用者来说没有区别.HashMap效率高于TreeMap;在需要排序的Map时才选用TreeMap.
---------------------------------------
import java.util.Map;
import java.util.TreeMap;
public class TestTreeMap {
public static void main(String[] args) {
Map<Integer,String> treemap1 = new TreeMap<>();
treemap1.put(450, "aa");
treemap1.put(55, "aa");
treemap1.put(99, "aa");
// 按照key递增的方式排序
for(Integer key:treemap1.keySet()) {
System.out.println(key+"---"+treemap1.get(key));
}
Map<Emp,String> treemap2 = new TreeMap<>();
treemap2.put(new Emp(10001,"xiaowang", 9000), "salary many");
treemap2.put(new Emp(10002,"xiaoli", 4000), "salary low");
treemap2.put(new Emp(10003,"xiaozhang", 9000), "salary many");
for(Emp temp:treemap2.keySet()) {
System.out.println(temp+"---"+treemap2.get(temp));
}
}
}
class Emp implements Comparable<Emp>{
int id;
String name;
double salary;
public Emp(int id, String name, double salary) {
super();
this.id = id;
this.name = name;
this.salary = salary;
}
@Override
public int compareTo(Emp o) {
if(this.salary>o.salary) {
return 1;
}else if(this.salary<o.salary) {
return -1;
}else {
if(this.id>o.id) {
return 1;
}else if(this.id<this.id) {
return -1;
}
return 0;
}
}
@Override
public String toString() {
System.out.print("id:"+id+" salary:"+salary+" name:"+name);
return "";
}
}
---------------------------------------
Set接口:
Set接口继承自Collection,Set接口中没有新增方法,方法和Collection保持完全一致.我们在前面通过List学习的方法,在Set中仍然适用.
Set容器特点:无序、不可重复.无序指Set中的元素没有索引,我们只能遍历查找;不可重复指不允许加入重复的元素.更确切地讲,
新元素如果和Set中某个元素通过equals()方法对比为true,则不能加入;甚至,Set中也只能放入一个null元素,不能多个.
Set常用的实现类有:HashSet、TreeSet等,我们一般使用HashSet.
HashSet的使用:
---------------------------------------
HashSet是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质就是一个简化版的HashMap),
因此,查询效率和增删效率都比较高.
--------------------------------------
import java.util.HashSet;
import java.util.Set;
public class TestHashSet {
public static void main(String[] args) {
Set<String> set1 = new HashSet<>();
set1.add("aaa");
set1.add("bbb");
set1.add("aaa"); // 相同的元素不会被加入
System.out.println(set1);
set1.remove("bbb");
System.out.println(set1);
Set<String> set2 = new HashSet<>();
set2.add("xiaozhang");
set2.addAll(set1);
System.out.println(set2);
}
}
-------------------------------------
TreeSet的使用:
TreeSet底层实际是用TreeMap实现的,内部维持了一个简化版的TreeMap,通过key来存储Set的元素.
TreeSet内部需要对存储的元素进行排序,因此,我们对应的类需要实现Comparable接口.这样,
才能根据compareTo()方法比较对象之间的大小,才能进行内部排序.
-------------------------------------
public class Test {
public static void main(String[] args) {
User u1 = new User(1001, "xiaowang", 18);
User u2 = new User(2001, "xiaoli", 5);
Set<User> set = new TreeSet<User>();
set.add(u1);
set.add(u2);
}
}
class User implements Comparable<User> {
int id;
String uname;
int age;
public User(int id, String uname, int age) {
this.id = id;
this.uname = uname;
this.age = age;
}
// 返回0 表示 this == obj 返回正数表示 this > obj 返回负数表示 this < obj
@Override
public int compareTo(User o) {
if (this.id > o.id) {
return 1;
} else if (this.id < o.id) {
return -1;
} else{
return 0;
}
}
}
-------------------------------------
使用TreeSet要点:
(1) 由于是二叉树,需要对元素做内部排序. 如果要放入TreeSet中的类没有实现Comparable接口,则会抛出异常:java.lang.ClassCastException.
(2) TreeSet中不能放入null元素.
使用Iterator迭代器遍历容器元素(List/Set/Map):
迭代器为我们提供了统一的遍历容器的方式:
------------------------------------
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class TestInterator {
public static void main(String[] args) {
testIteratorList();
testIteratorSet();
testIteratorMap();
}
public static void testIteratorMap() {
Map<Integer,String> map1 = new HashMap<>();
map1.put(10, "aa");
map1.put(20, "bb");
map1.put(30, "cc");
// 第一种遍历Map的方式
Set<Entry<Integer,String>> ss = map1.entrySet();
for(Iterator<Entry<Integer,String>> iter = ss.iterator();iter.hasNext();) {
Entry<Integer,String> temp = iter.next();
System.out.println(temp.getKey()+"--"+temp.getValue());
}
// 第二种遍历Map的方式
Set<Integer> keySet = map1.keySet();
for(Iterator<Integer> iter=keySet.iterator();iter.hasNext();) {
Integer key = iter.next();
System.out.println(key+"----"+map1.get(key));
}
}
public static void testIteratorList() {
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
// 使用Iterator遍历List
for(Iterator<String> iter=list.iterator();iter.hasNext();) {
String temp = iter.next();
System.out.println(temp);
}
}
public static void testIteratorSet() {
Set<String> set = new HashSet<>();
set.add("aaa");
set.add("bbb");
set.add("ccc");
// 使用Iterator遍历Set
for(Iterator<String> iter=set.iterator();iter.hasNext();) {
String temp = iter.next();
System.out.println(temp);
}
}
}
------------------------------------
iter.remove()在容器中删除此时迭代器所指向的元素
遍历集合的方法总结:
-----------------------------------
for(int i=0;i<list.size();i++){ // list为集合的对象名
String temp = (String)list.get(i);
System.out.println(temp);
}
for(String temp : list) {
System.out.println(temp);
}
for(Iterator iter= list.iterator();iter.hasNext();){
String temp = (String)iter.next();
System.out.println(temp);
}
Iterator iter =list.iterator();
while(iter.hasNext()){
Object obj = iter.next();
iter.remove(); // 如果要遍历时,删除集合中的元素,建议使用这种方式!
System.out.println(obj);
}
--------------------------------
for(String temp:set){
System.out.println(temp);
}
for(Iterator iter = set.iterator();iter.hasNext();){
String temp = (String)iter.next();
System.out.println(temp);
}
--------------------------------
Map<Integer, Man> maps = new HashMap<Integer, Man>();
Set<Integer> keySet = maps.keySet();
for(Integer id : keySet){
System.out.println(maps.get(id).name);
}
Set<Entry<Integer, Man>> ss = maps.entrySet();
for (Iterator iterator = ss.iterator(); iterator.hasNext();) {
Entry e = (Entry) iterator.next();
System.out.println(e.getKey()+"--"+e.getValue());
}
--------------------------------
Collections工具类:
类 java.util.Collections 提供了对Set、List、Map进行排序、填充、查找元素的辅助方法.
1. void sort(List) // 对List容器内的元素排序,排序的规则是按照升序进行排序.
2. void shuffle(List) // 对List容器内的元素进行随机排列.
3. void reverse(List) // 对List容器内的元素进行逆续排列 .
4. void fill(List, Object) // 用一个特定的对象重写整个List容器.
5. int binarySearch(List, Object) // 对于顺序的List容器,采用折半查找的方法查找特定对象.
Collections工具类的常用方法:
public class Test {
public static void main(String[] args) {
List<String> aList = new ArrayList<String>();
for (int i = 0; i < 5; i++){
aList.add("a" + i);
}
System.out.println(aList);
Collections.shuffle(aList); // 随机排列
System.out.println(aList);
Collections.reverse(aList); // 逆续
System.out.println(aList);
Collections.sort(aList); // 排序
System.out.println(aList);
System.out.println(Collections.binarySearch(aList, "a2"));
Collections.fill(aList, "hello");
System.out.println(aList);
}
}
表格数据存储(map和list结合):
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class TestStoreData {
public static void main(String[] args) {
Map<String,Object> row1 = new HashMap<>();
row1.put("id", 1001);
row1.put("姓名", "张三");
row1.put("薪水", 20000);
row1.put("入职日期", "2020.8.5");
Map<String,Object> row2 = new HashMap<>();
row2.put("id", 1002);
row2.put("姓名", "李四");
row2.put("薪水", 21332);
row2.put("入职日期", "2051.5.7");
Map<String,Object> row3 = new HashMap<>();
row3.put("id", 1003);
row3.put("姓名", "王五");
row3.put("薪水", 123123);
row3.put("入职日期", "2023.9.8");
List<Map<String,Object>> table1 = new ArrayList<>();
table1.add(row1);
table1.add(row2);
table1.add(row3);
for(Map<String,Object> row : table1) {
Set<String> keySet = row.keySet();
for(String key:keySet) {
System.out.print(key+"--"+row.get(key)+"\t");
}
System.out.println();
}
}
}