Java集合框架
java的集合是用来动态的存储对象的一种容器,使用数组也可以存储数组,但是有一个弊端就是使用数组的时候在初始化的时候数组的大小就是确定了的,无法更改,而使用集合就可以随心所欲的增加集合大小了。
java的集合框架结构如下图:
其中Collection与Map都是接口,没有具体的实现,先说一下它们的适用范围:
- Set:用于无序的、不可重复的元素
- List:用于有序的、可重复的元素
- Map:用于有映射关系的元素<key-value>
一、Collection中的方法
Collection col1 = new ArrayList();
1、获得集合大小并新增元素
//用size()获得集合大小
System.out.println(col1.size());
//添加新元素
col1.add(123);
2、将一个集合中的元素添加到另一个集合中
//addAll(Collection c)方法用来将参数的所有元素添加到接收器中
Collection coll1 = Arrays.asList(1,2,3);
col1.addAll(coll1);
3、集合可以直接打印出来,并且可以调用clear()清空集合,调用remove删除一个元素
//查看集合中的元素
System.out.println(col1);
//清空集合
col1.clear();
System.out.println(col1.size());
//remove(Object obj)删除一个元素
col1.remove(123);
4、判断集合中是否含有一个指定元素
//contains(Object obj)方法用来判断集合中是否包含指定元素,判断依据是根据元素所在类下的equals方法
System.out.println(col1.contains(123));
5、判断两个集合是否为包含关系以及求其交集
//containsAll(Collection c)方法用来判断两个集合是否为包含关系
Collection coll1 = Arrays.asList(123);
System.out.println(col1.containsAll(coll1));
//retainAll(Collection c)方法用来保存两个集合的交集并返回给接收器
col1.retainAll(coll1);
6、判断两个集合是否相等
//equals(Object obj)判断两个集合中的所有元素是否相同
System.out.println(col1.equals(coll1));
7、遍历集合中的所有元素,有三种方法,一种是使用数组,一种是使用增强for循环,另一种是使用迭代器
使用数组:
//toArray()将集合转化成数组
Object[] obj = coll1.toArray();
for(int i =0 ;i<obj.length;i++){
System.out.println("obj["+i+"] is "+obj[i]);
}
使用增强for循环:
//使用增强for循环遍历集合
for(Object ob:coll1){
System.out.println(ob);
}
使用迭代器:
//使用Iterator接口实现集合的遍历,利用hasNext()和next()进行迭代
Iterator iterator = coll1.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
二、继承Collection接口的List接口List的使用,相对于Collection中新增加了索引功能,可以根据index操作list,同时Collection接口中定义的方法也都可以使用
1、List的具体实现——ArrayList(List的主要实现类)
List list = new ArrayList();
list.add(123);
list.add("hello");
list.add("Tom");
System.out.println(list);
//在指定位置添加元素、获取指定位置的元素、删除指定索引位置的元素
list.add(0, "Cat");
System.out.println(list);
System.out.println(list.get(1));
System.out.println(list.remove(0));
System.out.println(list);
//设置指定位置的元素值
list.set(1, "Cat");
System.out.println(list);
//返回指定对象在list中首次出现、最后一次出现的索引值,没有该对象的话返回-1
list.add(123);
System.out.println(list.indexOf(123));
System.out.println(list.lastIndexOf(123));
//截取list的一部分当作新的List对象返回,左闭右开
List subList = list.subList(1, 3);
System.out.println(subList);
2、List的具体实现——LinkedList
LinkedList适用于频繁的插入、删除操作,使用链表实现
3、List的具体实现——Vector是一个从java1.0就有的类了,可以保证线程安全
因为LinkedList与Vector跟ArrayList的用法一样,就不举例子了
三、继承Collection接口的Set接口
Set中的元素具有无序性、不可重复性,常用的方法都是继承自Collection的,这里就不赘述了
1、Set的具体实现——HashSet(Set的主要实现类)
元素的存储方式是使用的哈希结构,当向Set中添加类对象时会先调用hasCode()方法,计算该对象的哈希值,如果Set中已经有对象与之哈希值相同则调用equals()方法比较两个对象是否相同,所以要求要添加到Set的类对象的类要重写hasCode()和equals()方法
package com.kexin.day1;
import java.util.HashSet;
import java.util.Set;
public class TestSet {
public static void main(String[] args) {
testHashSet();
}
public static void testHashSet(){
Set set = new HashSet();
set.add(new Student("Tom",12));
set.add(new Student("Jerry",11));
set.add(new Student("Jack",13));
set.add(new Student("Tom",12));
System.out.println(set);
}
}
class Student{
private String name;
private int 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;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
2、Set的另一个实现类TreeSet
- 添加的元素必须是同一类型的才可以,否则会运行时报错
- 如果要将类对象加入到TreeSet中时,可以通过以下两种方式实现(直接贴代码了,注释很详细)
package com.kexin.day1;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
/**
* TreeSet的最大不同是它要求加入的元素类型必须一致才可以
* 而且支持两种方式的元素排序
* ①自然排序②制定排序
* @author KeXin
*
*/
public class TestTreeSet {
public static void main(String[] args) {
test1();
test2();
}
//自然排序
public static void test1(){
Set set = new TreeSet();
Person1 p1 = new Person1("Tom",12);
Person1 p2 = new Person1("Jerry",13);
Person1 p3 = new Person1("Dili",11);
Person1 p4 = new Person1("Jack",12);
set.add(p1);
set.add(p2);
set.add(p3);
set.add(p4);
System.out.println("自然排序 "+set);
}
//制定排序
public static void test2(){
//制定排序虽然不要求类要继承Comparable接口但是new一个Comparator接口对象作为Set的构造器参数
Comparator com = new Comparator() {
//在这里重写compare函数,用来指定按照哪个属性进行排序
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Person && o2 instanceof Person){
Person p1 = (Person) o1,p2 = (Person) o2;
int i = ((Integer)p1.getAge()).compareTo((Integer)p2.getAge());
if(i == 0){
return p1.getName().compareTo(p2.getName());
}
return i;
}
return 0;
}
};
Set set = new TreeSet<>(com);
Person p1 = new Person("Tom",12);
Person p2 = new Person("Jerry",13);
Person p3 = new Person("Dili",11);
Person p4 = new Person("Jack",12);
set.add(p1);
set.add(p2);
set.add(p3);
set.add(p4);
System.out.println("制定排序 "+set);
}
}
//实现自然排序的时候需要将要加入的类继承Comparable并实现其接口compareTo
class Person1 implements Comparable{
private String name;
private int 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;
}
public Person1(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person1 [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person1 other = (Person1) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//重写Comparable的compareTo方法,指定按对象的哪个属性来排序
@Override
public int compareTo(Object o) {
if(o instanceof Person1){
//指定按照年龄排序,如果年龄相同再按名字排序
int i = ((Integer)this.age).compareTo(((Person1)o).getAge());
if (i == 0){
//如果想反过来排序则只需要在返回值之前加一个负号
return this.name.compareTo(((Person1) o).getName());
}else{
return i;
}
}
return 0;
}
}
3、Set的另一个实现类LinkedHashSet
用链表维护添加到集合中的元素的顺序,打印顺序与添加顺序相同。不常用
Map-----------是key-value键值对,其中key用Set存放,value用Collection存放
|_____HashMap---------主要实现类,很常用
| |____添加put(key,value) putAll(map) 删除remove(key) clear() 获得get(key) 大小size()
| |____遍历Set keySet() Collection values() Set entrySet()
| |____判断containsKey(key) containsValue(value) isEmpty() equals(obj)
|_____TreeMap---------它对于key的要求类似于TreeSet对于元素的要求,同样提供两种排序方式
|_____LinkedHashMap---不常用
很简单,也很常用,都在代码里了:
package com.kexin.day1;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
/**
* @author KeXin
*
* Map-----------是key-value键值对,其中key用Set存放,value用Collection存放
* |_____HashMap---------主要实现类,很常用
* | |____添加put(key,value) putAll(map) 删除remove(key) clear() 获得get(key) 大小size()
* | |____遍历Set keySet() Collection values() Set entrySet()
* | |____判断containsKey(key) containsValue(value) isEmpty() equals(obj)
* |_____TreeMap---------它对于key的要求类似于TreeSet对于元素的要求,同样提供两种排序方式
* |_____LinkedHashMap---不常用
*
*/
public class TestMap {
public static void main(String[] args) {
testHashMap();
// testTreeMap();
}
public static void testHashMap(){
Map map = new HashMap();
map.put(1, "Tom");
map.put(2, "Jerry");
map.put(3, "Dili");
map.put(4, "Jack");
System.out.println(map);
System.out.println(map.get(2));
map.remove(2);
System.out.println(map);
//遍历keys
System.out.print("keys are ");
for(Object o:map.keySet()){
System.out.print(o+"\t");
}
System.out.println();
//遍历values
System.out.print("values are ");
Iterator i = map.values().iterator();
while(i.hasNext()){
System.out.print(i.next()+"\t");
}
System.out.println();
//遍历entry
System.out.print("entries are ");
for(Object o:map.entrySet()){
Map.Entry entry = (Entry) o;
System.out.print(entry+"\t");
}
System.out.println();
//遍历entry另一种方式
System.out.print("entries are ");
for(Object o:map.keySet()){
System.out.print(o+"="+map.get(o)+"\t");
}
}
}
TreeMap参考TreeSet,不说了