为什么出现集合类:
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式(java的集合都在 java.util包下 )
数组和集合类都是容器,有何不同:
数组虽然也可以存储对象,但长度是固定的;集合长度可变。数组中可以存储基本数据类型,但集合只能存储对象。
集合类特点:
集合只用于存储对象,集合长度可变,集合可存储不同类型的对象。
迭代器:Iterator
方法:
1. hasNext() 如果仍有元素可以迭代,则返回 true。
2. next() 返回迭代的下一个元素。
Collection类方法
其接口为 Iterator ,
1. isEmpty() 如果此 collection 不包含元素,则返回true
2. size() 返回此 collection 中的元素数。
3. contains(Object o) 如果此 collection 包含指定的元素,则返回 true
Collection 接口有两个子接口:
List (列表) Set(集)
List:可存放重复元素,元素存取是有序的
有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
List中有iterator()方法,返回按适当顺序在列表的元素上进行迭代的迭代器。
ArrayList (数组列表)
ArrayList 类是List 接口的大小可变数组的实现。
ArrayList (数组列表)方法:
1. get(int index) 返回此列表中指定位置上的元素。
2. add(E e) 将指定的元素添加到此列表的尾部。
3. contains(Object o) 如果此列表中包含指定的元素,则返回 true。
增强for循环
增强for循环的作用: 简化迭代器的书写格式。(注意:增强for循环的底层还是使用了迭代器遍历。)
增强for循环的适用范围: 如果是实现了Iterable接口的对象或者是数组对象都可以使用增强for循环。
增强for循环的缺点:增强for循环和iterator遍历的效果是一样的,也就说增强for循环的内部也就是调用iteratoer实现的,但是增强for循环有些缺点,例如不能在增强循环里动态的删除集合内容、不能获取下标等。
增强for循环的格式:
for(数据类型 变量名 :遍历的目标){ //数据类型 变量名:声明一个变量用来接收遍历目标遍历后的元素
}
//迭代的两种常用方法
for(Iterator iter=list.iterator();iter.hasNext();){
System.out.println(iter.next());
}
Iterator iter=list.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
package collectionpackage;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class App {
public static void main(String[] args) {
List list = new ArrayList();
list.add("1234");
list.add(100);
list.add(new Integer(20));
list.add(new Long(666));
System.out.println(list.size());
//遍历集合
for(int i=0;i<list.size();i++){
Object obj = (Object)list.get(i);
System.out.println(obj);
}
//迭代器
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//另一种方法
for (Iterator it0=list.iterator();it0.hasNext();){
System.out.println(it0.next());
}
//转化
for (int i=0;i<list.size();i++){
Object obj = list.get(i);
if(obj instanceof String){
System.out.println("String" + (String)obj);
}
else if(obj instanceof Integer){
System.out.println("Integer" + (Integer)obj);
}
else if(obj instanceof Long){
System.out.println("Long" + (Long)obj);
}
}
}
}
package collectionpackage;
import java.util.ArrayList;
import java.util.List;
public class App1 {
public static void main(String[] args) {
/**
* 创建集合,存放String[tom,tomas,tomsLee] 存放Integer[100,200,300]
* 存放student[name,age,sex]
*/
List list = new ArrayList();
list.add(new String("tom"));
list.add(new String("tomas"));
list.add("tomsLee"); // 可以简写,自动装箱
list.add(new Integer(100));
list.add(new Integer(200));
list.add(300); // 简写
Student s1 = new Student();
s1.setName("student-1");
s1.setAge(20);
s1.setSex('M'); // 这样写太麻烦
list.add(new Student("student-2", 30, 'F')); // 简写
list.add(new Student("student-3", 40, 'F'));
// 遍历集合
Object o = null;
for (int i = 0; i < list.size(); i++) {
o = list.get(i);
if (o instanceof String) {
System.out.println("String类 :" + (String) o);
System.out.println("String类 :" + ((String) o).toString()); // 二者一样
} else if (o instanceof Integer) {
System.out.println("Integer类 :" + (Integer) o);
System.out.println("Integer类 :" + ((Integer) o).intValue()); // 二者一样
} else if (o instanceof Student) {
Student s = (Student) o;
System.out.println("Student类 :" + s.getName() + ":" + s.getAge() + " " + s.getSex());
}
}
System.out.println("*************************************************");
// 使用泛型集合
List<Student> list1 = new ArrayList<Student>();
list1.add(new Student("张三", 15, 'F'));
list1.add(new Student("李四", 16, 'M'));
list1.add(new Student("王五", 17, 'F'));
// 遍历泛型集合
for (int i = 0; i < list1.size(); i++) {
Student ss = list1.get(i);
System.out.println(ss.getName() + ":" + ss.getAge() + ss.getSex());
}
//增强for循环
for(Student stmp : list1){
System.out.println(stmp.getName() + ":" + stmp.getAge() + stmp.getSex());
}
}
}
package collectionpackage;
public class Student {
private String name;
private int age;
private char sex;
public Student() {
super();
}
public Student(String name, int age, char sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
}
LinkedList 链表
List 接口的链接列表实现,此类实现 Deque 接口
LinkedList方法:
1.add(E e) 将指定元素添加到此列表的结尾。
2. addFirst(E e) 将指定元素插入此列表的开头。
3. addLast(E e) 将指定元素添加到此列表的结尾。
4. contains(Object o) 如果此列表包含指定元素,则返回 true。
5. get(int index) 返回此列表中指定位置处的元素。
6. getLast() 返回此列表的最后一个元素。
7. getFirst() 返回此列表的第一个元素。
package collectionpackage;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class App2 {
public static void main(String[] args) {
Deque<String> dq = new LinkedList();
dq.add("大柱子");
dq.add("二狗子");
dq.add("三伢子");
//迭代器
System.out.println("*******迭代器*******");
Iterator it = dq.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//增强for循环
System.out.println("*******增强for循环*******");
for(String trmp : dq){
System.out.println(trmp);
}
/**
* 创建ArrayList集合,存放100个student对象,名字从tom0~tom99,年龄0~99;
* 给出对象s = new Student("tom",9);
* 判断s在List中是否存在
*/
List<Student> list100 = new ArrayList<Student>();
for(int i=0;i<100;i++){
list100.add(new Student("tom" + i,i));
}
Student s = new Student("tom9",9);
System.out.println(list100.contains(s)); //之所以返回值为false,是因为s.equals()方法默认判断的是内存地址是否相同,要在student类中重写equals方法
}
}
ArrayList和LinkedList区别:
ArrayList内部是使用可増长数组实现的,所以是用get和set方法是花费常数时间的,但是如果插入元素和删除元素,除非插入和删除的位置都在表末尾,否则代码开销会很大,因为里面需要数组的移动。
LinkedList是使用双链表实现的,所以get会非常消耗资源,除非位置离头部很近。但是插入和删除元素花费常数时间。
Set:一个不包含重复元素的 collection(继承collection的接口)
Set:一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2)
的元素对 e1
和 e2
,并且最多包含一个 null 元素。不可以存放重复元素,元素存取无序。先判断hashcode是否相同,如果不同,可以存放,如果相同,再判断equals方法是否相同。因此如果hashcode不同,即使equals相同也能添加。
查找元素时,和List不同,Set不能通过遍历集合来查找,必须用迭代器。
set接口中常用的类:
HashSet:线程不安全,存取速度快
TreeSet:线程不安全,可以对Set集合中的元素进行排序
HashSet添加方法:
1. 同一物理对象(堆中对象地址相同),add()方法不会添加重复的
2. 不同对象
a) hashcode相同,equals不同——>可以添加
b) hashcode相同,equals相同——>不可以添加
c) hashcode不相同,equals不同——>可以添加
d) hashcode不相同,equals相同——>可以添加
package collectionpackage;
import java.util.HashSet;
import java.util.Set;
public class HashSetDemo {
public static void main(String[] args){
Set<Person> set1 = new HashSet<Person>();
System.out.println("**********1.相同物理地址 ——》不可以添加**********");
Person p = new Person("tom",10);
set1.add(p);
set1.add(p);
set1.add(p);
System.out.println(set1.size());
System.out.println("**********2.不同物理地址,hashcode=1,equals=false ——》可以添加**********");
Set<Person> set2 = new HashSet<Person>();
Person p1 = new Person("tom",10);
Person p2 = new Person("tom",10);
set2.add(p1);
set2.add(p2);
System.out.println(set2.size());
System.out.println("**********3.不同物理地址,hashcode相同,equals=true ——》不可以添加**********");
Set<Person> set3 = new HashSet<Person>();
Person p3 = new Person("tom",10);
Person p4 = new Person("tom",10);
set3.add(p3);
set3.add(p4);
System.out.println(set3.size());
System.out.println("**********4.不同物理地址,hashcode不同,equals=false ——》可以添加**********");
Set<Person> set4 = new HashSet<Person>();
Person p5 = new Person("tom",10);
Person p6 = new Person("tom",10);
set4.add(p5);
set4.add(p6);
System.out.println(set4.size());
System.out.println("**********5.不同物理地址,hashcode不同,equals=true ——》可以添加**********");
Set<Person> set5 = new HashSet<Person>();
Person p7 = new Person("tom",10);
Person p8 = new Person("tom",10);
set5.add(p7);
set5.add(p8);
System.out.println(set5.size());
}
}
package collectionpackage;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
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;
}
// public int hashCode(){
// return name == null ?age :name.hashCode() + age;
// }
public int hashCode(){
//return 1; //保证hashcode相同
return super.hashCode(); //保证hashcode不同
}
public boolean equals(Object obj){
return true;
}
}
重写hashcode和equals()方法
package collectionpackage;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
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;
}
public int hashCode() {
return name == null ? age : name.hashCode() + age;
}
// public int hashCode(){
// //return 1; //保证hashcode相同
// return super.hashCode(); //保证hashcode不同
// }
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
// 精准判断
if (obj.getClass() == Person.class) {
Person p = (Person) obj;
// name是否相同
boolean nameEqu = false;
if (this.name == null) {
if (p.name == null) {
nameEqu = true;
} else {
nameEqu = false;
}
}
// name不空
else {
nameEqu = name.equals(p.name);
}
// age是否相同
boolean ageEqu = (this.age == p.age);
return nameEqu && ageEqu;
}
return false;
}
}
package collectionpackage;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetDemo {
public static void main(String[] args){
System.out.println("**********判断hashset集合是否存在指定对象**********");
Set<Person> set = new HashSet<Person>();
Person p1 = new Person("tom",10);
Person p2 = new Person("tom",10);
Person p3 = new Person("tomas",10);
Person p4 = new Person("tom",12);
set.add(p1);
set.add(p2);
set.add(p3);
set.add(p4);
System.out.println(set.size());
//判断是否含有指定元素
System.out.println(set.contains(p2)); //true
System.out.println(set.contains(new Person("tom",10))); //true
System.out.println(set.contains(new Person("tom",13))); //false
//遍历set集合(只能利用迭代器)
Iterator<Person> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//增强for循环
for(Person pp : set){
System.out.println(pp);
}
//从set中删除元素
set.remove(new Person("tom",10));
System.out.println(set.size());
}
}
HashSet:是线程不安全的,存取速度快。通过equals方法和hashCode方法来保证元素的唯一性。
TreeSet:线程不安全,可以对Set集合中的元素进行排序。通过compareTo或者compare方法来保证元素的唯一性。元素以二 叉树形式存放。
TreeSet: 基于 TreeMap
的 NavigableSet
实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator
进行排序,具体取决于使用的构造方法。
package collectionpackage;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
/**
* 自定义比较器,实现对象的大小比较
* 按照年龄判断大小
*/
Comparator<Person> comp = new Comparator<Person>() {
public int compare(Person o1,Person o2) {
if (o1==null){
if(o2==null){
return 0;
}
else{
return -1;
}
}
else{
if(o2==null){
return 1;
}
else{
return o1.getAge()-o2.getAge();
}
}
}
};
TreeSet<Person> ts = new TreeSet<Person>(comp);
ts.add(new Person("p1",10));
ts.add(new Person("p1",10));
ts.add(new Person("p3",30));
ts.add(new Person("p2",20));
System.out.println(ts.size());
for(Iterator<Person> it=ts.iterator();it.hasNext();){
Person p=it.next();
System.out.println(p.getName()); //输出结果为p1,p2,p3
}
}
}
package collectionpackage;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
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;
}
public int hashCode() {
return name == null ? age : name.hashCode() + age;
}
// public int hashCode(){
// //return 1; //保证hashcode相同
// return super.hashCode(); //保证hashcode不同
// }
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
// 精准判断
if (obj.getClass() == Person.class) {
Person p = (Person) obj;
// name是否相同
boolean nameEqu = false;
if (this.name == null) {
if (p.name == null) {
nameEqu = true;
} else {
nameEqu = false;
}
}
// name不空
else {
nameEqu = name.equals(p.name);
}
// age是否相同
boolean ageEqu = (this.age == p.age);
return nameEqu && ageEqu;
}
return false;
}
}
Map:key-value
Map与Collection:
1.Map与Collection在集合框架中属并列存在
2.Map存储的是键值对
3.Map存储元素用put方法,Collection使用add方法
4.Map集合没有直接取出元素的方法,而是先转成Set集合,再通过迭代获取元素
5.Map集合中键要保证唯一性
Map的键存储在Set中(Set不能存储重复元素)
Map方法:
1.put (k key,v value) 将指定的值与此映射中的指定键关联(可选操作)。
2.keySet() 返回此映射中包含的键的Set视图
3.entrySet() 返回此映射中包含的映射关系的Set视图。返回的是 键-值 对
4.get (Object key) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回null。
package collectionpackage;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
Map<String, Person> map = new HashMap<String, Person>();
map.put("1", new Person("张三", 20));
map.put("2", new Person("李四", 20));
map.put("3", new Person("王五", 20));
map.put("4", new Person("赵六", 20));
System.out.println(map.size());
// 循环map的所有entry
Set<Entry<String, Person>> entries = map.entrySet();
for (Entry<String, Person> entry : entries) { // 增强for循环
String key = entry.getKey();
Person p = entry.getValue();
System.out.println(key + ": " + p.getName() + p.getAge());
}
// 通过key集合遍历map
Set<String> str = map.keySet();
for (String k : str) {
Person pp = map.get(k);
System.out.println(k + " :" + pp.getName() + pp.getAge());
}
}
}
package collectionpackage;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
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;
}
public int hashCode() {
return name == null ? age : name.hashCode() + age;
}
// public int hashCode(){
// //return 1; //保证hashcode相同
// return super.hashCode(); //保证hashcode不同
// }
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
// 精准判断
if (obj.getClass() == Person.class) {
Person p = (Person) obj;
// name是否相同
boolean nameEqu = false;
if (this.name == null) {
if (p.name == null) {
nameEqu = true;
} else {
nameEqu = false;
}
}
// name不空
else {
nameEqu = name.equals(p.name);
}
// age是否相同
boolean ageEqu = (this.age == p.age);
return nameEqu && ageEqu;
}
return false;
}
}
map里有三种集合:
1.keys set 集合
2.values 集合
3.entry (键-值对)集合
集合框架中的工具类
Collections:
1.对集合进行查找
2.取出集合中的最大值,最小值
3.对List集合进行排序
List<String> list = new ArrayList<String>();
list.add("abc");
list.add("de");
list.add("中国");
list.add("a");
String st = Collections.max(list);
System.out.println(st);
//获取最大最小值
System.out.println("------获取最大最小值------");
System.out.println(Collections.max(list));
System.out.println(Collections.min(list));
//交换两个元素位置
System.out.println("------交换两个元素位置------");
Collections.swap(list, 1, 3);
for (int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
//对集合排序
System.out.println("------对集合排序------");
Collections.sort(list);
for (int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
Arrays(数组工具类):
1.将数组转化成List集合
2.对数组进行排序
3.对数组进行二分查找
方法:
1.copyOf (int [] original , newLength(新数组的长度)) 拷贝数组
2.binarySearch (int[] a,int key) 使用二分搜索法来搜索指定的 int 型数组,以获得指定的值(key)。
3.binarySearch (int[] a,int fromIndex,int toIndex,int key) 使用二分搜索法来搜索指定的 int 型数组的范围,以获得指定 的值。(索引范围不包括toIndex)
4.aslist(T... a) 返回一个受指定数组支持的固定大小的列表。
返回值类型 函数名(参数类型... 形式参数){
执行语句;
}
变长参数只能有一个,且必须是最后一个
package collectionpackage;
import java.util.Arrays;
public class ArraysDemo {
public static void main(String[] args) {
/**
* 实现数组的复制
*/
int[] arr = new int[] {1,3,5,7};
int[] newarr = Arrays.copyOf(arr, 2);
}
}
集合嵌套
package collectionpackage;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CollectionConvertDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("toma");
list.add("tom");
list.add("tomas");
list.add("tom");
list.add("tomson");
list.add("toma");
// 去重
Set<String> set = new HashSet<String>(list);
System.out.println(list.size());
System.out.println(set.size());
// 集合嵌套
List<List<String>> grade = new ArrayList<List<String>>();
int no = 1;
for(int i=1;i<=10;i++){
List<String> classes = new ArrayList<String>();
grade.add(classes);
for(int j=1;j<=50;j++){
String temp = "" + i + "班" + j + "号" + " " + "tom" + no ;
classes.add(temp);
no++;
}
}
}
}
hash是将众多对象打散,分成若干个空间,当查询某个对象时首先将其定位到某个区间上,缩小了搜寻空间
使用HashMap实现集合嵌套:
package collectionpackage;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class HashMapDemo {
public static void main(String[] args) {
//利用HashMap实现集合嵌套
//班级集合
Map<Integer, Map<String, String>> classes = new HashMap<Integer, Map<String, String>>();
//名单集合
Map<String,String> names = null;
int no = 1;
//向班级集合添加班级(名单集合)
for(int i = 1;i<=10;i++){
names = new HashMap<String,String>();
classes.put(i, names);
for(int j = 1;j<=50;j++){
names.put(i + "班" + j + "号:", "tom" + no);
no++;
}
}
//遍历班级集合的EntrySet
for(Entry<Integer, Map<String, String>> entry : classes.entrySet()){
Integer key = entry.getKey();//班号
Map<String, String> values = entry.getValue();//名单集合
for(Entry<String, String> entry0 : values.entrySet()){
String stuNo = entry0.getKey();
String stuName = entry0.getValue();
System.out.println(stuNo + stuName);
}
}
System.out.println("--------------------");
//使用KeySet遍历集合
for(Integer classNo : classes.keySet()){
Map<String, String> map = classes.get(classNo);
for(String stuNo : map.keySet()){
String stuName = map.get(stuNo);
System.out.println(stuNo + stuName);
}
}
}
}