collection父接口:
特点:代表一组任意类型的对象无序,无下标、不能重复。
collection集合使用
创建student实现类
package CollectionStudy;
public class student {
private String name;
private int age;
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", 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 student(){
}
public student(String name,int age){
// super();
this.name=name;
this.age=age;
}
}
package CollectionStudy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class demo1 {
public static void main(String[] args){
//新建collection对象
Collection collection=new ArrayList();
student st0=new student("张三",12);
student st1=new student("张四",13);
student st2=new student("张五",14);
student st3=new student("张六",15);
//添加数据到集合中
collection.add(st0);
collection.add(st1);
collection.add(st2);
collection.add(st3);
System.out.println("元素个数为:"+ collection.size());
System.out.println(collection.toString());
//删除
collection.remove(st1);
System.out.println(collection.toString());
collection.remove(new student("张四",13));//新创建一个对象,指向的内存地址不同
System.out.println(collection.toString());
//遍历:增强for
for(Object a:collection){
//需要通过强转进行
student s=(student)a;
System.out.println(a);
}
//遍历:迭代器
//hasNext()判断有没有元素;next()获取下一个元素
Iterator it=collection.iterator();
while (it.hasNext()){
student st= (student)it.next();//强制转换
System.out.println(st);
System.out.println("*******************************************");
// it.remove();
System.out.println(st);
}
//遍历:for+迭代器
for(Iterator i1=collection.iterator();i1.hasNext();){
student st5=(student)i1.next();
System.out.println(st5);
}
//判断
System.out.println(collection.contains(st2));//输出true
//输出false,新创建的对象所指向的内存地址不同
System.out.println(collection.contains(new student("张三",12)));//输出false
//清空只是将集合中的元素进行删除,其student创建的对象不会被删除
collection.clear();
System.out.println(collection.toString());
}
}
List接口:有序、有下标、元素可重复
方法:
void add(int index,Object o)//在index位置插入对象o。
Boolean addAll(int index,Collection c)//将一个集合中的元素添加得到此集合中的index位置
Object get(int index)//返回集合中指定位置的元素
List sublist(int fromIndex,int toIndex)//返回fromIndex和toIndex之间的集合元素
package CollectionStudy;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class demo2 {
//List接口:有序有下标可重复
public static void main(String[] args){
List list=new ArrayList<>();
//添加元素
list.add("手机");
list.add("pg");
list.add("dddd");
list.add("dddd1");
list.add("dddd2");
list.add("dddd3");
System.out.println("元素个数"+list.size());
//删除元素
list.remove("pg");
list.remove(0);
System.out.println(list.size());
//遍历
for (int i=0;i<list.size();i++){
System.out.println(list.get(i));//根据角标打印元素,是Object类型
}
//增强for
for(Object a:list){
System.out.println(a);
}
//迭代器
Iterator it=list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//for迭代器
for(Iterator i=list.iterator();i.hasNext();){
System.out.println(i.next());
}
//列表迭代器
ListIterator itlist=list.listIterator();
System.out.println("*************从前往后*************");
while (itlist.hasNext()){
System.out.println(itlist.nextIndex()+":"+itlist.next());
}
System.out.println("************从后往前***************");
while (itlist.hasPrevious()){
System.out.println(itlist.previousIndex()+":"+itlist.previous());
}
}
}
package CollectionStudy;
import java.util.ArrayList;
import java.util.List;
public class demo3 {
public static void main(String[] args){
//创建集合
List list=new ArrayList();
//添加元素(自动装箱),集合不能保存基本数据类型,只能保存引用类型
list.add(20);
list.add(30);
list.add(40);
list.add(50);
System.out.println("元素个数"+list.size());
System.out.println(list.toString());
//删除操作
//list.remove(20);//根据下标进行删除,超过下标时,会报错
// list.remove((Object)20);//通过强制转型实现删除;或通过list.remove(new Integer(20));进行删除元素20;或通过下标list.remove(0)
System.out.println(list.toString());
//subList方法:左闭右开
System.out.println(list.subList(1,2));
}
}
ListIterator和Iterator的区别:
ListIterator可以向前或向后遍历,添加、删除、修改元素
List集合实现类:ArrayList(数组结构实现,查询快,增删慢,运行效率快,线程不安全);Vector(数组结构实现,查询快,增删慢,运行效率慢,线程安全);LinkedList(链表结构实现,增删快,查询慢)
ArrayList:
package CollectionStudy;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class demo4 {
//ArrayList:存储结构:数组,查找遍历速度快、增删慢
public static void main(String[] args){
ArrayList arrayList=new ArrayList<>();
//添加元素
student s1=new student("zhangsan",11);
student s2=new student("lisi",13);
student s3=new student("wangwu",14);
student s4=new student("geliu",15);
student s5=new student("qiqi",16);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
arrayList.add(s3);
arrayList.add(s4);
arrayList.add(s5);
System.out.println(arrayList.toString());
//有两个删除时,只删除一个元素,可通过下标删除,也可以通过元素删除
arrayList.remove(s3);
arrayList.remove(new student("zhangsan",11));//要想实现删除,需要重写equals()方法,object中的equals(this==obj)方法
System.out.println(arrayList.toString());
//遍历元素:迭代器
Iterator iterator=arrayList.iterator();
while (iterator.hasNext()){
student s=(student)iterator.next();
System.out.println(s.toString());
}
//列表迭代器
ListIterator its=arrayList.listIterator();
while ((its.hasNext())){
student ss=(student)its.next();
System.out.println(ss.toString());
}
//判断
System.out.println(arrayList.contains(s1));
System.out.println(arrayList.isEmpty());
//查找
System.out.println(arrayList.indexOf(s5));//查找元素位置
}
}
重写equals方法后可以实现新增对象的删除
@Override
public boolean equals(Object obj){
//判断是否为同一个对象
if(this==obj){
return true;
}
//判断是否为空
if(obj==null){
return false;
}
//判断是否为student类型
if(obj instanceof student){
student s= (student)obj;
//比较属性
if(this.name.equals(s.getName()) && this.age==s.getAge()){
return true;
}
}
//不满足条件返回false
return false;
}
ArrayList源码分析:
默认容量大小:DEFAULT_CAPACITY=10; 如果为向集合中添加任何元素时,容量为0,添加一个元素之后容量变为10.当元素为10时,扩容变为15,每次扩容大小是原来的1.5倍
存放元素:EMPTY_ELEMENTDATA
实际元素个数:size
添加元素:add()
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
Vector:(数组结构实现,线程安全,运行速度较慢)
package CollectionStudy;
import java.util.Enumeration;
import java.util.Vector;
public class demo5 {
public static void main(String[] args){
//创建集合
Vector vector=new Vector<>();
//添加元素
vector.add(1);
vector.add(2);
vector.add(3);
vector.add(4);
vector.add(5);
//删除元素
vector.remove(1);
//遍历元素:通过枚举
Enumeration enumeration=vector.elements();
while (enumeration.hasMoreElements()){
int o=(int)enumeration.nextElement();
System.out.println(o);
}
}
}
LinkedList:链表结构实现,增删快、查询慢
package CollectionStudy;
import java.util.LinkedList;
public class demo6 {
//LinkedList:存储结构:双向链表
public static void main(String[] args){
LinkedList linkedList=new LinkedList<>();
//添加元素
student s1=new student("zhangsan",12);
student s2=new student("lisi",13);
student s3=new student("wangwu",14);
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
System.out.println(linkedList.size());
System.out.println(linkedList.toString());
//删除元素
linkedList.remove(s1);
//遍历操作
for(int i=0;i<linkedList.size();i++){
System.out.println(linkedList.get(i));
}
}
}
泛型:其本质是参数化类型,把类型作为参数传递,常见形式有泛型类、泛型接口、泛型方法。
语法:<T,…>T称为类型占位符,表示一直引用类型,
好处:提高代码重用性,防止类型转换异常,提高代码安全性
泛型只能使用引用类型;不同泛型对象不能相互复制
泛型类创建
package CollectionStudy;
public class MyGeneric<T> {
//泛型类:语法:类名<T>,T表示类型占位符,表示一种引用类型
//使用泛型T,不能通过T,new一个对象,不能实例化
T t;
//添加方法
public void show(T t){
System.out.println(t);
}
//使用泛型作为方法返回值
public T getT(){
return t;
}
//泛型类使用
}
泛型使用
package CollectionStudy;
public class TestGeneric {
//泛型类使用
public static void main(String[] args){
//使用泛型类创建对象
MyGeneric<String> myGeneric=new MyGeneric<String>();
myGeneric.t="hello";
myGeneric.show("hi");
String string=myGeneric.getT();
System.out.println(myGeneric.t);//hello
MyGeneric<Integer> myGeneric1=new MyGeneric<Integer>();
myGeneric1.t=1;
myGeneric1.show(222);
Integer integer=myGeneric1.getT();
System.out.println(myGeneric.t);//hello
}
}
泛型接口:
package CollectionStudy;
public interface GenericFace<T> {
//泛型接口:不能泛型静态常量
String name="zhang";
T server(T t);
}
package CollectionStudy;
public class MyInterface implements GenericFace<String> {
@Override
public String server(String s) {
System.out.println(s);
return null;
}
}
实例化对象
GenericFace t=new MyInterface();
t.server("hhhhh");
泛型方法:
package CollectionStudy;
public class GenericMethod {
//泛型方法:语法:<T>返回值类型
public <T> void show(T t){
System.out.println("泛型方法"+t);
}
public <T> T show1(T t){
System.out.println("泛型方法"+t);
return t;
}
}
GenericMethod genericMethod=new GenericMethod();
genericMethod.show("1");
genericMethod.show(1);
genericMethod.show1(555);
泛型集合:创建集合使用泛型容易导致其内容中有很多类型强制转换时无法准确判断,参数化类型、类型安全的集合,强制集合元素的类型必须一致
特点:编译时即可检查,非运行时抛出异常;访问时,不必类型转换(拆箱);不同泛型之间引用不能互相赋值,泛型不存在多态
Set接口:(无序、无下标、元素不可重复):其方法全部继承
Collection中的方法:HashSet、TreeSet。
package CollectionStudy.Setface;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class demo {
public static void main(String[] args){
//Set:特点:无序(打印顺序与插入顺序无关),没有下标,不能重复
//创建集合
Set<String> set=new HashSet<String>();
set.add("a");
set.add("g");
set.add("b");
System.out.println("元素个数"+set.size());
System.out.println(set.toString());
// 删除
set.remove("a");
System.out.println(set.toString());
// 遍历:增强for
for(String st:set){
System.out.println(st);
}
// 遍历:迭代器
Iterator<String> it= set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
//判断
System.out.println(set.contains("b"));
System.out.println(set.isEmpty());
}
}
HashSet:基于HashCode实现计算元素存放位置;当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
package CollectionStudy.Setface;
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person(String name, int age) {
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;
}
}
package CollectionStudy.Setface;
import java.util.HashSet;
public class demo2 {
public static void main(String[] args){
HashSet<Person> person=new HashSet<>();
Person p1=new Person("zhang",11);
Person p2=new Person("zhang1",12);
Person p3=new Person("zhang2",13);
Person p4=new Person("zhang3",14);
Person p5=new Person("zhang4",15);
person.add(p1);
person.add(p2);
person.add(p3);
person.add(p4);
person.add(new Person("zhang",11));//可以添加,不是同一对象
System.out.println(person.toString());
person.remove(p3);
}
}
HashSet存储过程:
(1)根据hashcode计算保存位置,如果此位置为空,则直接保存,如果不为空,则执行第二步
(2)再执行equals()方法,如果equals方法为true,则认为是重复,否则形成链表。
如果需要实现创建名字、年龄相等的对象为同一对象,需重写hashCode方法和equals方法
@Override
public int hashCode(){
int n1=this.name.hashCode();
int n2=this.age;
return n1+n2;
}
@Override
public boolean equals(Object object){
if(this==object){
return true;
}
if(object==null){
return false;
}
if(object instanceof Person){
Person person=(Person)object;
if(this.name.equals(person.getName()) && this.age==person.getAge()){
return true;
}
}
return false;
}
重写hashCode通过判断hashcode是否相等。
通过重写,在执行以下操作时,可以实现添加不成功,否则能添加成功,因为创建的新对象所指地址不同,equals原方法中只通过(this==object)来判断两个对象是否相等。
Person p1=new Person(“zhang”,11);
person.add(p1);
person.add(new Person(“zhang”,11));
TreeSet:采用红黑树的形式实现,基于排列顺序实现元素不重复;
实现了SortedSet接口,对集合元素自动排序;元素对象的类型必须实现Comparable接口,指定排序规则;通过CompareTo方法确定是否为重复元素。
package CollectionStudy.Setface;
public class Person1 implements Comparable<Person1> {
private String name;
private int age;
@Override
public int compareTo(Person1 p){
//比较规则,先按姓名进行比较,如何在按年龄进行比较
int n1=this.getName().compareTo(p.getName());
int n2=this.age-p.getAge();
return n1==0?n2:n1;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person1(String name, int age) {
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;
}
}
如果没有实现compareTo接口,会报错误提示,原因在于无法进行排序
package CollectionStudy.Setface;
import java.util.TreeSet;
public class demo3 {
public static void main(String[] args){
//存储结构:红黑树;要求:元素必须实现Compareable接口
//红黑树小的在左,大的在右,需要进行比较
TreeSet<Person1> person1=new TreeSet<>();
Person1 p1=new Person1("zhang",11);
Person1 p2=new Person1("zhang1",12);
Person1 p3=new Person1("zhang2",13);
Person1 p4=new Person1("zhang3",14);
person1.add(p1);
person1.add(p2);
person1.add(p3);
person1.add(p4);
System.out.println(person1.toString());
}
}
comparetor接口:在创建集合时就指定比较规则
package CollectionStudy.Setface;
import java.util.Comparator;
import java.util.TreeSet;
public class demo6 {
//TreeSet集合使用:comparetor:实现进制比较(比较器);comparable:可比较的
public static void main(String[] args){
TreeSet<Person> per=new TreeSet<>(new Comparator<Person>() {
//创建集合并指定比较规则,先比较年龄后比较姓名
@Override
public int compare(Person o1, Person o2) {
int age=o1.getAge()-o2.getAge();
int name=o1.getName().compareTo(o2.getName());
return age==0?name:age;
}
});
Person p1=new Person("zhang",13);
Person p2=new Person("zhang",11);
Person p3=new Person("zh",11);
per.add(p1);
per.add(p2);
per.add(p3);
System.out.println(per.toString());
}
}
//输出结果:[Person{name='zh', age=11}, Person{name='zhang', age=11}, Person{name='zhang', age=13}]
TreeSet案例:使用TreeSet集合实现字符串按照长度进行排序
package CollectionStudy.Setface;
import java.util.Comparator;
import java.util.TreeSet;
public class demo4 {
public static void main(String[] args){
//实现字符串按照长度进行比较,默认情况下按照字母表中的顺序进行比较
TreeSet<String> treeSet=new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1=o1.length()-o2.length();
//长度一样通过字母表中顺序进行比较
int n2=o1.compareTo(o2);
return n1==0?n2:n1;
}
});
treeSet.add("124");
treeSet.add("333");
treeSet.add("2");
System.out.println(treeSet.toString());
}
}
Map集合使用:特点:用于存储任意键值对。键:无序、无下标、不允许重复(唯一);值:无序、无下标、允许重复
Map父接口:存储一对数据,无序、无下标,键不可重复,值可重复。
方法:V put(K key,V value)//将对象存入集合中,关联键值,key重复则覆盖原值。
Object get(Object key)//根据键获取对应的值。
Set//返回所有key。
Collection values() //返回包含所有值的collection集合。
Set<Map.Entry<K,V>>//键值匹配的Set集合
package CollectionStudy.Mapface;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class demo1 {
//Map接口:存储键值对;键不能重复,值可重复;无序.
public static void main(String[] args){
//创建map集合
Map<String ,String> map= new HashMap<>();
//添加元素:put()实现元素添加
map.put("cn","zg");
map.put("uk","am");
map.put("usa","a");
// map.put("usa","a"); //键不可重,键重复时,后面的键将覆盖前面的键
System.out.println(map.size());
System.out.println(map.toString());
//删除元素
map.remove("usa");
System.out.println(map.size());
//遍历:使用KeySet()实现
Set<String> keyset=map.keySet();
//或者直接在里面添加for(String key:map.keySet())
for(String key:keyset){
System.out.println(key+"......."+map.get(key));//通过key得到value
}
//使用entrySet()方法,map.entrySet(),有键有值
Set<Map.Entry<String,String>> entries=map.entrySet();
for(Map.Entry<String,String> entry:entries){
System.out.println(entry.getKey()+".........."+entry.getValue());
}
}
}
HashMap:线程不安全,运行效率快,允许用null作为key或是value。HashMap的默认初始容量为16,默认加载因子为0.75,即当里面的数据超过0.75时,进行扩容。
HashMap集合使用:存储结构:哈希表(数组+链表+红黑树)
package CollectionStudy.Mapface;
import java.util.HashMap;
public class demo {
public static void main(String[] args){
//创建集合:hashset:使用key是根据hashcode、equals作为判断是否重复的。
HashMap<Student,String> students=new HashMap<Student,String>();
//添加元素
Student s1=new Student("zhang1",1111);
Student s2=new Student("zhang2",1112);
Student s3=new Student("zhang3",1113);
Student s4=new Student("zhang4",1114);
students.put(s1,"a1");
// students.put(s1,"a55555");//此时输出为Student{name='zhang1', stuno=1111}=a55555而不再是Student{name='zhang1', stuno=1111}=a1
// students.put(s1,"a1");//键相同时,后面的键将覆盖前面的键,值也随之改变
students.put(s2,"a2");
students.put(s3,"a2");//键不同,值相同时,可以添加成功
students.put(s4,"a4");
students.put(new Student("zhang1",1111),"a1");//此时可以添加成功,在堆里面新建对象,对象地址不一样,所以可以实现添加
//如果想要实现不能添加成功,需要去重,需要重写hashcode和equals方法
System.out.println(students.size());
System.out.println(students.toString());
//删除元素 remove
students.remove(s1);
//遍历 KeySet()
for(Student key:students.keySet()){
System.out.println(key.toString()+":"+students.get(key));
}
}
}
实现去重:重写hashcode方法和equals方法
直接通过idea生成hashcode和equals方法即可:在实现类中重写方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return stuno == student.stuno &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, stuno);
}
HashMap总结:
1.hashmap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16;
2.当元素个数大于值(16*0.75)时,会进行扩容,扩容后的大小为原来大小的2倍,目的是减少调整元素的个数;
3.当每个链表长度大于8,并且元素个数小于64时,会调整为红黑树,目的是提高执行效率;
4.当链表长度小于6时,调整为链表;
5.在jdk1.8以前,链表是头插入,1.8以后,链表是尾插入。
TreeMap:实现了SortedMap接口,可以对key自动排序。
package CollectionStudy.Mapface;
import java.util.Map;
import java.util.TreeMap;
public class demo2 {
//TreeMap:
public static void main(String[] args){
TreeMap<Student,String> treeMap=new TreeMap<Student,String>();
Student s1=new Student("zhang1",1);
Student s2=new Student("zhang2",2);
Student s3=new Student("zhang3",3);
treeMap.put(s1,"1");
treeMap.put(s2,"2");
treeMap.put(s3,"3");
System.out.println(treeMap.toString());
//遍历:使用keySet实现
for(Student s:treeMap.keySet()){
System.out.println(s+":"+treeMap.get(s));//通过键去获取值
}
//遍历:使用entrySet比使用keySet效率更高
for(Map.Entry<Student,String> entry:treeMap.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue());
}
}
}
package CollectionStudy.Mapface;
import CollectionStudy.Setface.Person1;
import java.util.Comparator;
import java.util.Objects;
public class Student implements Comparable<Student> {
private String name;
private int stuno;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return stuno == student.stuno &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, stuno);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", stuno=" + stuno +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuno() {
return stuno;
}
public void setStuno(int stuno) {
this.stuno = stuno;
}
public Student() {
}
public Student(String name, int stuno) {
this.name = name;
this.stuno = stuno;
}
//需要实现comparable
@Override
public int compareTo(Student s){
//比较规则,先按姓名进行比较,如何在按年龄进行比较
int n1=this.getName().compareTo(s.getName());
int n2=this.stuno-s.getStuno();
return n1==0?n2:n1;
}
}
注:
TreeSet和TreeMap需要实现comparable接口,重写里面的compareTo方法对实现接口类中的属性参数进行比较。遍历通过keySet实现或entrySet实现,两者相比较:entrySet遍历的效率更高
//遍历:使用keySet实现 for(Student s:treeMap.keySet()){
System.out.println(s+":"+treeMap.get(s));//通过键去获取值 } //遍历:使用entrySet比使用keySet效率更高 for(Map.Entry<Student,String>
entry:treeMap.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue()); }
collections工具类:集合工具类,定义了除了存取以外的集合常用方法。
public static void reverse(List<?> list)//反转集合中的元素
public static void shuffle(List<?> list)//随机重置集合元素的顺序
public static void sort(List list)//升序排序(元素类型必须实现comparable接口)
package CollectionStudy.Mapface;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class demo3 {
public static void main(String[] args){
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(5);
list.add(4);
//sort排序
//排序之前
System.out.println(list.toString());
//排序之后打印
Collections.sort(list);
System.out.println(list.toString());
//binarySearch
int i=Collections.binarySearch(list,5);
System.out.println(i);//打印下标
//copy复制
List<Integer> d=new ArrayList<>();
for(int j=0;j<list.size();j++){
d.add(0);
}
Collections.copy(d,list);
System.out.println(d.toString());
//list转换为数组
list.toArray(new Integer[0]);
}
}