一、什么是集合

  • 概念:对象的容器,定义了对多个对象进行操作的常用方法。可以实现数组的功能。
  • 和数组区别:
    • (1)数组长度固定,集合长度不固定
    • (2)数组可以存储基本类型和引用类型,集合只能存储引用类型
  • 位置:Java.util*

二、Collection体系集合

1、Collection父接口

  • 特点:代表一组任意类型的对象,无序、无下标、不能重复。
  • 方法:
    • boolean add(Object obj) //添加一个对象。
    • boolean addAll(Collection c) //将一个集合中的所有对象添加到此集合中。
    • void clear() //清空此集合中的所有对象。
    • boolean contains(Object o) //检查此集合中是否包含o对象
    • boolean equals(Object o)//比较此集合是否与指定对象相等。
    • boolean isEmpty) //判断此集合是否为空
    • boolean remove(0bject o) //在此集合中移除o对象.
    • int size() //返回此集合中的元素个数。
    • Object[] toArray() //将此集合转换成数组。
package com.jjl.Collection;/*
Collection接口的是使用
1、添加元素
2、删除记录
3、遍历元素
4、判断*/import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class Demo01 {public static void main(String[] args) {//创建一个集合Collection collection = new ArrayList();//1、添加元素collection.add("苹果");collection.add("西瓜");collection.add("榴莲");collection.add("香蕉");System.out.println("元素个数"+collection.size());System.out.println(collection);//2、删除collection.remove("香蕉");//collection.clear();//清空System.out.println("删除之后的个数"+collection.size());//遍历元素//遍历方法一:增强forfor (Object object : collection){System.out.println(object);}//遍历方法二:迭代器(专门用来遍历集合的一种方法)//迭代器iterator//hasNext();有没有下一个元素//Next();获取下一个元素//remove();删除当前元素Iterator it=collection.iterator();while (it.hasNext()){String object= (String)it.next();System.out.println(object);//it.remove();//删除}//System.out.println("迭代删除之后的个数"+collection.size());//判断是否有某个元素System.out.println(collection.contains("西瓜"));//判断是否为空System.out.println(collection.isEmpty());}
}
输出:
元素个数4
[苹果, 西瓜, 榴莲, 香蕉]
删除之后的个数3
苹果
西瓜
榴莲
苹果
西瓜
榴莲
true
false

实际应用

package com.jjl.Collection;public class Student {private String name;private int age;public Student(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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

主程序调用

package com.jjl.Collection;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class Demo02 {public static void main(String[] args) {//新建Collection对象Collection collection=new ArrayList();Student s1=new Student("张三",23);Student s2=new Student("张四",24);Student s3=new Student("张五",25);//1添加数据collection.add(s1);collection.add(s2);collection.add(s3);System.out.println("元素个数"+collection.size());System.out.println(collection.toString());//增强for循环System.out.println("=========增强for循环遍历=========");for (Object object : collection){Student s=(Student) object;System.out.println(s.toString());}//迭代器:hasNext() next(); remove(); 迭代器过程中不能使用collection的删除方法System.out.println("=========迭代器Iterator遍历=========");Iterator it = collection.iterator();while (it.hasNext()){Student s = (Student) it.next();System.out.println(s);}}
}
输出:
元素个数3
[Student{name='张三', age=23}, Student{name='张四', age=24}, Student{name='张五', age=25}]
=========增强for循环遍历=========
Student{name='张三', age=23}
Student{name='张四', age=24}
Student{name='张五', age=25}
=========迭代器Iterator遍历=========
Student{name='张三', age=23}
Student{name='张四', age=24}
Student{name='张五', age=25}

2、List子接口

  • 特点:有下标、有序、元素可以重复
  • 方法
    • void add (int,index,Object o) //在index位置插入对象o.
    • boolean addAll(int index,Collection c) //将一个集合中的元素添加到此集合中的index位置。
    • 0bject get(int index) //返回集合中指定位置的元素。
    • List subList(int fromIndex,int toIndex) //返回fromIndex和toIndex之间的集合元素。
package com.jjl.Collection;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;/*
List子接口的使用*/
public class Demo03 {public static void main(String[] args) {//先创建一个集合List list=new ArrayList<>();//添加元素list.add("苹果");list.add("vivo");list.add(0,"Lenovo");System.out.println("元素个数"+list.size());System.out.println(list.toString());//删除元素//list.remove(0);//删除一个元素//遍历//使用forSystem.out.println("=========使用for遍历==========");for (int i=0;i<list.size();i++){System.out.println(list.get(i));}//增强forSystem.out.println("===============增强for遍历=============");for (Object object:list){System.out.println(object);}//使用迭代器System.out.println("============使用迭代器遍历=============");Iterator it = list.iterator();while (it.hasNext()){System.out.println(it.next());}//使用列表迭代器,ListIterator可以向前向后遍历,可以添加删除元素System.out.println("============使用列表迭代器===========");ListIterator lit=list.listIterator();System.out.println("==========从前往后============");while (lit.hasNext()){System.out.println(lit.nextIndex()+":"+lit.next());//打印角标和属性}System.out.println("==========从后往前============");while (lit.hasPrevious()){System.out.println(lit.previousIndex()+":"+lit.previous());//打印角标和属性}//判断System.out.println(list.contains("苹果"));System.out.println(list.isEmpty());//获取位置(下标)System.out.println(list.indexOf("vivo"));}
}
输出:
元素个数3
[Lenovo, 苹果, vivo]
=========使用for遍历==========
Lenovo
苹果
vivo
===============增强for遍历=============
Lenovo
苹果
vivo
============使用迭代器遍历=============
Lenovo
苹果
vivo
============使用列表迭代器===========
==========从前往后============
0:Lenovo
1:苹果
2:vivo
==========从后往前============
2:vivo
1:苹果
0:Lenovo
true
false
2

List接口使用2

package com.jjl.Collection;import java.util.ArrayList;
import java.util.List;public class Demo04 {public static void main(String[] args) {//创建集合List list=new ArrayList();//添加数字数据(自动装箱)list.add(20);list.add(30);list.add(40);list.add(50);list.add(60);System.out.println("元素个数:"+list.size());System.out.println(list.toString());//删除元素(默认使用脚本删除,不能之间使用元素删除)//list.remove(0);//如果要使用元素属性删除,需要将元素转成Integerlist.remove(new Integer(20));System.out.println("删除后的元素个数:"+list.size());System.out.println(list.toString());//补充方法sublist,返回子集合List subList=list.subList(1,3); //获取1到3的元素,包含1不包含3System.out.println(subList.toString());}
}
输出:
元素个数:5
[20, 30, 40, 50, 60]
删除后的元素个数:4
[30, 40, 50, 60]
[40, 50]

3、List实现类

  • ArrayList

    • 数组结构实现,查询块、增删慢;
    • JDK1.2版本,运行效率块、线程不安全。
    • 源码分析:
      • 默认容量:DEFAULT_CAPACITY = 10;

        • 如果没有向集合中添加任何元素时,容量就是:0
      • 存放元素的数组:transient Object[] elementData
      • 实际元素个数:size
  • Vector:
    • 数组结构实现,查询快、增删慢;
    • ·JDK1.0版本,运行效率慢、线程安全。
  • LinkedList:
    • 链表结构实现,增删快,查询慢。

3.1、ArrayList

package com.jjl.Collection;import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;/*
ArrayList的使用
存储结构:数组,查找遍历速度快,增删慢*/
public class Demo5 {public static void main(String[] args) {//创建集合ArrayList arrayList=new ArrayList<>();//1添加元素Student s1=new Student("可可",18);Student s2=new Student("爱爱",17);Student s4=new Student("明明",25);Student s3=new Student("小小",19);Student s5=new Student("玲玲",20);arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);arrayList.add(s4);arrayList.add(s5);System.out.println("============元素总个数===========");System.out.println("元素个数"+arrayList.size());System.out.println("\n========打印所有元素===========");System.out.println(arrayList.toString());//删除//方法一:System.out.println("\n=======使用下标或者元素属性名称删除元素===========");arrayList.remove(1);//可以用下标,也可以用元素属性System.out.println(arrayList.toString());//方法二:System.out.println("\n========使用元素源数据进行删除,需要重写object方法===========");arrayList.remove(new Student("小小",19));//如果需要这种方法删除,则就要重写Student的obj方法System.out.println(arrayList.toString());//遍历(使用迭代器)System.out.println("\n============迭代器遍历法===========");Iterator it=arrayList.iterator();while (it.hasNext()) {Student s = (Student) it.next();System.out.println(s.toString());}//遍历(列表迭代器)System.out.println("\n============列表迭代器遍历法===========");ListIterator lit= arrayList.listIterator();while (lit.hasNext()) {Student s = (Student) lit.next();System.out.println(s.toString());}//判断System.out.println("\n============判断元素是否存在===========");System.out.println(arrayList.contains(new Student("玲玲",20)));//此方法只能在重写了equals方法之后才能使用System.out.println(arrayList.isEmpty());//判断是否为空//查找System.out.println("\n============查找元素的下标===========");System.out.println(arrayList.indexOf(s1));}
}
输出:
============元素总个数===========
元素个数5========打印所有元素===========
[Student{name='可可', age=18}, Student{name='爱爱', age=17}, Student{name='小小', age=19}, Student{name='明明', age=25}, Student{name='玲玲', age=20}]=======使用下标或者元素属性名称删除元素===========
[Student{name='可可', age=18}, Student{name='小小', age=19}, Student{name='明明', age=25}, Student{name='玲玲', age=20}]========使用元素源数据进行删除,需要重写equals方法===========
[Student{name='可可', age=18}, Student{name='明明', age=25}, Student{name='玲玲', age=20}]============迭代器遍历法===========
Student{name='可可', age=18}
Student{name='明明', age=25}
Student{name='玲玲', age=20}============列表迭代器遍历法===========
Student{name='可可', age=18}
Student{name='明明', age=25}
Student{name='玲玲', age=20}============判断元素是否存在===========
true
false============查找元素的下标===========
0

重写Student类的equals方法的比较方式

@Overridepublic 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;}}return false;}

3.2、Vector

package com.jjl.Collection;import java.util.Enumeration;
import java.util.Vector;/*
Vector集合的使用*/
public class Demo06 {public static void main(String[] args) {Vector vector=new Vector<>();vector.add("草莓");vector.add("芒果");vector.add("西瓜");vector.add("香蕉");System.out.println("元素个数"+vector.size());//遍历vector.remove(0);//可以根据角标和元素//遍历,可以用for//枚举器遍历Enumeration en=vector.elements();while (en.hasMoreElements()){String o=(String) en.nextElement();System.out.println(o);}//判断System.out.println(vector.contains("西瓜"));}}
输出:
元素个数4
芒果
西瓜
香蕉
true

3.3、LinkedList

package com.jjl.Collection;import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;/*
LinkedList的使用*/
public class Demo07 {public static void main(String[] args) {//创建集合LinkedList linkedList=new LinkedList<>();//添加元素Student s1=new Student("张三",23);Student s2=new Student("张四",24);Student s3=new Student("张五",25);linkedList.add(s1);linkedList.add(s2);linkedList.add(s3);linkedList.add(s3);System.out.println("=====打印元素个数=======");System.out.println("元素个数:"+linkedList.size());System.out.println("\n======打印所有元素=======");System.out.println(linkedList.toString());//2、删除linkedList.remove(new Student("张三",23));//由于重写过equals方法,所以可以使用元素内容删除System.out.println("\n=========删除元素之后的元素个数:===========");System.out.println(linkedList.size());//3遍历System.out.println("\n=====for遍历========");for (int i=0;i<linkedList.size();i++){System.out.println(linkedList.get(i));}System.out.println("\n=========增强for遍历========");for(Object object:linkedList){Student s=(Student) object;System.out.println(s.toString());}System.out.println("\n======迭代器遍历========");Iterator it=linkedList.iterator();while (it.hasNext()){Student s=(Student) it.next();System.out.println(s.toString());}System.out.println("\n======列表迭代器遍历========");ListIterator lit=linkedList.listIterator();while (lit.hasNext()){Student s=(Student) lit.next();System.out.println(s.toString());}System.out.println("\n======判断========");System.out.println(linkedList.contains(s2));//判断元素是否存在System.out.println(linkedList.isEmpty());//判断是否为空System.out.println("\n======查找========");System.out.println(linkedList.indexOf(s3));}
}
输出:
=====打印元素个数=======
元素个数:4======打印所有元素=======
[Student{name='张三', age=23}, Student{name='张四', age=24}, Student{name='张五', age=25}, Student{name='张五', age=25}]=========删除元素之后的元素个数:===========
3=====for遍历========
Student{name='张四', age=24}
Student{name='张五', age=25}
Student{name='张五', age=25}=========增强for遍历========
Student{name='张四', age=24}
Student{name='张五', age=25}
Student{name='张五', age=25}======迭代器遍历========
Student{name='张四', age=24}
Student{name='张五', age=25}
Student{name='张五', age=25}======列表迭代器遍历========
Student{name='张四', age=24}
Student{name='张五', age=25}
Student{name='张五', age=25}======判断========
true
false======查找========
1

三、泛型

  • Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
  • 常见形式有泛型类、泛型接口、泛型方法。
  • 语法:
    • <T…> T称为类型占位符,表示一种引用类型。
  • 好处:
    • (1)提高代码的重用性
    • (2)防止类型转换异常,提高代码的安全性

1、泛型类

创建泛型类

package com.jjl.MyGeneric;/*
泛型类
语法,类名
T是类型占位符,表示一种引用类型,如果编写多个使用,逗号隔开。*/
public class Demo01<T> {//使用泛型//1创建变量T t;//作为方法的参数public void show(T t){System.out.println(t);}//3使用泛型作为方法的返回值public T getT(){return t;}
}

主程序测试

package com.jjl.MyGeneric;import com.jjl.Exception.Demo02.MyException;public class TestGeneric {public static void main(String[] args) {//使用泛型类T对象//注意:1泛型只能使用引用类型。//2不同泛型之间不能相互复制Demo01<String> demo01=new Demo01<String>();//demo01.t="hello";demo01.show("大家好");String string=demo01.getT();Demo01<Integer> demo011=new Demo01<Integer>();//demo011.t=100;demo011.show(200);Integer integer= demo011.getT();}
}
输出:
大家好
200

2、泛型接口

创建接口

package com.jjl.MyGeneric;/*
泛型接口
语法,接口<T>
注意,不能使用泛型创建静态常量*/
public interface MyInterface<T> {//String name="张三";T server(T t);}

接口实现类:方法一
直接指定参数类型

package com.jjl.MyGeneric;public class MyInterfaceMpl implements MyInterface<String>{@Overridepublic String server(String s) {System.out.println(s);return s;}
}

接口实现类:方法二
不指定参数类型,让调用实现类时指定

package com.jjl.MyGeneric;public class MyInterfacemp2<T> implements MyInterface<T>{@Overridepublic T server(T t) {System.out.println(t);return t;}
}

主程序调用

     //方法一MyInterfaceMpl impl=new MyInterfaceMpl();impl.server("xxxxxxxxxxxx");//方法二MyInterfacemp2<Integer> ipl2=new MyInterfacemp2<>();ipl2.server(2000);

3、泛型方法

创建一个泛型方法

package com.jjl.MyGeneric;/*
泛型方法
语法:<T>方法返回值*/
public class MyGenericthod {//泛型方法//格式一:public <T> void show(T t){System.out.println("泛型方法"+t);}/*格式二:public <T> t show(T t){System.out.println("泛型方法"+t);return t;}*/
}

主程序调用

//调用泛型方法MyGenericthod myGenericthod=new MyGenericthod();//不用指定类型,会自动根据给的值确定类型myGenericthod.show("字符串");myGenericthod.show(200);myGenericthod.show(1.14);
输出:
泛型方法字符串
泛型方法200
泛型方法1.14

4、泛型集合

  • 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
  • 特点:
    • 编译时即可检查,而非运行时抛出异常。
    • 访问时,不必类型转换(拆箱)。
    • 不同泛型之间引用不能相互赋值,泛型不存在多态。
package com.jjl.MyGeneric;import com.jjl.Collection.Student;import java.util.ArrayList;
import java.util.Iterator;public class Demo02 {public static void main(String[] args) {//通过泛型,指定集合里的数据类型ArrayList<String> arrayList=new ArrayList<String>();arrayList.add("xxxx");arrayList.add("yyy");for (String string:arrayList){System.out.println(string);}ArrayList<Student> arrayList2=new ArrayList<Student>();Student s1=new Student("张三",23);Student s2=new Student("张四",24);Student s3=new Student("张五",25);arrayList2.add(s1);arrayList2.add(s2);arrayList2.add(s3);Iterator<Student> it= arrayList2.iterator();while (it.hasNext()){Student s=it.next();//由于“Iterator<Student>”已经指定了迭代器的类型,所以不用再转成student类型了。System.out.println(s.toString());}}
}
输出:
xxxx
yyy
Student{name='张三', age=23}
Student{name='张四', age=24}
Student{name='张五', age=25}

四、Set集合

  • 特点:无须、无下标、元素不可重复。
  • 方法:全部继承自Collection中的方法。
package com.jjl.Set;import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;/*
Set接口的使用
特点:无序、没有下标,不能重复*/
public class Demo01 {public static void main(String[] args) {//创建集合Set<String> set=new HashSet<>();//1、添加数据set.add("xiaomi");set.add("vivo");set.add("oppo");set.add("HUAWEI");System.out.println("元素个数:"+set.size());System.out.println(set.toString());//2删除set.remove("xiaomi");//3遍历//方法一:增强forSystem.out.println("\n=========增强for遍历=========");for (String string:set){System.out.println(string);}//方法二:迭代器System.out.println("\n=========使用迭代器遍历=========");Iterator<String> it=set.iterator();while (it.hasNext()){String sting= it.next();System.out.println(sting);}//判断System.out.println("\n=========判断元素是否存在=========");System.out.println(set.contains("HUAWEI"));System.out.println("\n=========判断是否为空=========");System.out.println(set.isEmpty());}
}
输出:
元素个数:4
[xiaomi, oppo, vivo, HUAWEI]=========增强for遍历=========
oppo
vivo
HUAWEI=========使用迭代器遍历=========
oppo
vivo
HUAWEI=========判断元素是否存在=========
true=========判断是否为空=========
false

1、Set实现类

1.1HashSet 【重点】

  • 基于HashCode计算元素存放位置。
  • 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
package com.jjl.Set;import java.util.HashSet;
import java.util.Iterator;/*
HashSet集合的使用
存储结构:哈希表(数组+链表+红黑树)*/
public class Demo02 {public static void main(String[] args) {//新建集合HashSet<String> hashSet=new HashSet<String>();//1添加元素hashSet.add("刘德华");hashSet.add("成龙");hashSet.add("杨幂");hashSet.add("热巴");System.out.println("元素个数:"+hashSet.size());System.out.println(hashSet.toString());//删除System.out.println("\n=======删除后的元素个数========");hashSet.remove("热巴");System.out.println("元素个数:"+hashSet.size());//遍历增强forSystem.out.println("\n=======增强for遍历========");for (String string:hashSet){System.out.println(string);}System.out.println("\n=======迭代器遍历========");Iterator<String> it=hashSet.iterator();while (it.hasNext()){System.out.println(it.next());}//判断System.out.println("\n=======判断元素是否存在,判断元素是否为空========");System.out.println(hashSet.contains("热巴"));System.out.println(hashSet.isEmpty());}}
输出:
元素个数:4
[成龙, 杨幂, 热巴, 刘德华]=======删除后的元素个数========
元素个数:3=======增强for遍历========
成龙
杨幂
刘德华=======迭代器遍历========
成龙
杨幂
刘德华=======判断元素是否存在,判断元素是否为空========
false
false

重写hashcode和equlas用于排重的方法
新建set类

package com.jjl.Set;import java.util.Objects;public class Person {private String name;private int 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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}//以下是通过快捷方式一键生成的hashcode和equals用于去重的方法@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof Person)) return false;Person person = (Person) o;if (age != person.age) return false;return name != null ? name.equals(person.name) : person.name == null;}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}//手动写的hashcode和equals用于去重的方法//    @Override
//    public int hashCode() {//        int n1=this.name.hashCode();
//        int n2=this.age;
//        return n1+n2;
//    }
//
//    @Override
//    public boolean equals(Object obj) {//        if (this==obj){//            return true;
//        }
//        if (obj==null) {//            return false;
//        }
//        if (obj instanceof Person){//            Person p=(Person) obj;
//            if(this.name.equals(p.getName())&&this.age== p.getAge()){//                return true;
//            }
//        }
//        return false;
//    }}

重写hashcode和equlas用于排重的方法的快捷方法:

主程序调用

package com.jjl.Set;import java.util.HashSet;/*
hashset使用
存储过程:
(1)根据hashcode计算保存的位置。如果此位置为空。则直接保存。如果不为空执行第二步。
(2)再执行equals方法。如果equals方法为true,则认为是重复,否则形成链表*/
public class Demo03 {public static void main(String[] args) {HashSet<Person> person=new HashSet<>();Person p1=new Person("刘德华",50);Person p2=new Person("成龙",60);Person p3=new Person("林志玲",20);Person p4=new Person("宋小宝",10);person.add(p1);person.add(p2);person.add(p3);person.add(p4);person.add(p4);//以这种方式,Java会认为是重复数据,不能加入Hashset//以这种方式又可以加入重复的的数据,如果想让它加入不进去,就需要重写Person类的hashcode方法和equals方法person.add(new Person("宋小宝",10));System.out.println("打印元素个数:"+person.size());System.out.println(person);}
}

1.2、TreeSet:

  • 基于排列顺序实现元素不重复。
  • 实现了SortedSet接口,对集合元素自动排序。
  • 元素对象的类型必须实现Comparable接口,指定排序规则。
  • 通过CompareTo方法确定是否为重复元素。

简单使用

package com.jjl.Set;import java.util.Iterator;
import java.util.TreeSet;/*
TreeSet的使用
存储结构:红黑树*/
public class Demo04 {public static void main(String[] args) {//1创建集合TreeSet<String> treeSet=new TreeSet<>();//1添加元素treeSet.add("xyz");treeSet.add("abc");treeSet.add("hello");System.out.println("打印元素个数:"+treeSet.size());System.out.println(treeSet);//自动排序treeSet.remove("hello");System.out.println("\n删除后元素个数:"+treeSet.size());System.out.println("\n=====增强for遍历=========");for(String string:treeSet){System.out.println(string);}System.out.println("\n=====迭代器遍历=========");Iterator<String> it=treeSet.iterator();while (it.hasNext()){System.out.println(it.next());}System.out.println("\n=====判断=========");System.out.println(treeSet.contains("abc"));}
}
打印:
打印元素个数:3
[abc, hello, xyz]删除后元素个数:2=====增强for遍历=========
abc
xyz=====迭代器遍历=========
abc
xyz=====判断=========
true

复杂参数

package com.jjl.Set;import java.util.TreeSet;
/*
存储方式:红黑树
要求:元素必须要实现Comparable接口,compareTo()方法的返回值为0时,则意味着为重复的*/
public class Demo05 {public static void main(String[] args) {//创建集合TreeSet<Person> person=new TreeSet<>();Person p1=new Person("刘德华",50);Person p2=new Person("成龙",60);Person p3=new Person("林志玲",20);Person p4=new Person("宋小宝",10);person.add(p1);person.add(p2);person.add(p3);person.add(p4);System.out.println("打印元素个数:"+ person.size());System.out.println(person);}
}

由于上面treeset的元素时Person类,所以就需要Person实现Comparable接口,compareTo()方法的返回值为0时,则意味着为重复的

package com.jjl.Set;import java.util.Objects;public class Person implements Comparable<Person>{private String name;private int 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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}//以下是通过快捷方式一键生成的hashcode和equals用于去重的方法@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof Person)) return false;Person person = (Person) o;if (age != person.age) return false;return name != null ? name.equals(person.name) : person.name == null;}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}/*** @param o the object to be compared.* @return*///先按姓名比,再按年龄比@Overridepublic int compareTo(Person o) {int n1=this.getName().compareTo(o.getName());int n2=this.age-o.getAge();return n1==0?n2:n1;}//手动写的hashcode和equals用于去重的方法//    @Override
//    public int hashCode() {//        int n1=this.name.hashCode();
//        int n2=this.age;
//        return n1+n2;
//    }
//
//    @Override
//    public boolean equals(Object obj) {//        if (this==obj){//            return true;
//        }
//        if (obj==null) {//            return false;
//        }
//        if (obj instanceof Person){//            Person p=(Person) obj;
//            if(this.name.equals(p.getName())&&this.age== p.getAge()){//                return true;
//            }
//        }
//        return false;
//    }}

定制比较,不用单独在Person类实现Comparable接口

package com.jjl.Set;import java.util.Comparator;
import java.util.TreeSet;/*
TreeSet集合的使用
Comparator:实现定制比较*/
public class Demo06 {public static void main(String[] args) {//通过匿名内部类的方式,实现比较方式,就不用在Person类里面去实现实现Comparable接口了TreeSet<Person> person=new TreeSet<>(new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {int n1=o1.getAge()-o2.getAge();int n2=o1.getName().compareTo(o2.getName());return n1==0?n2:n1;}});Person p1=new Person("刘德华",50);Person p2=new Person("成龙",60);Person p3=new Person("林志玲",20);Person p4=new Person("宋小宝",10);person.add(p1);person.add(p2);person.add(p3);person.add(p4);System.out.println("打印元素个数:"+ person.size());System.out.println(person);}
}

案例
使用Treeset集合实现字符串按照长度进行排序

package com.jjl.Set;import java.util.Comparator;
import java.util.TreeSet;/*
通过定制比较规则
使用Treeset集合实现字符串按照长度进行排序*/
public class Demo07 {public static void main(String[] args) {TreeSet<String> treeSet=new TreeSet<>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {int n1=o1.length()-o2.length();int n2=o1.compareTo(o2);return n1==0?n2:n1;}});//添加数据treeSet.add("helloword");treeSet.add("pingguo");treeSet.add("lisi");treeSet.add("zhangsan");treeSet.add("beijing");treeSet.add("cat");treeSet.add("nanjing");treeSet.add("xian");System.out.println(treeSet.toString());}
}
输出:
[cat, lisi, xian, beijing, nanjing, pingguo, zhangsan, helloword]

三、Map集合

1、Map父接口

  • 特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复。
  • 方法:
  • V put(K key,V value)//将对象存入到集合中,关联键值。key重复则覆盖原值。
  • Object get(Object key)//根据键获取对应的值。
  • Set< K >//返回所有key。
  • Collection < V > values() //返回包含所有值的Collection集合。
  • Set<Map. Entry<K,V>>//键值匹配的Set集合。

基本使用

package com.jjl.Map;import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*
map接口使用
特点:(1)存储键值对(2)键不能重复,值可以重复(3)无序*/
public class Demo01 {public static void main(String[] args) {//创建map集合Map<String,String> map=new HashMap<>();map.put("CN","中国");map.put("UK","英国");map.put("USA","美国");map.put("JP","日本");//map.put("JP","riben");//如果,添加重复的value,那么则会覆盖前面的value和key。System.out.println("打印元素个数:"+map.size());System.out.println(map);System.out.println("\n=========删除之后的个数=========");map.remove("JP");System.out.println("打印元素个数:"+map.size());//3遍历//使用keySet();System.out.println("\n========keyset()遍历===========");Set<String> keyset=map.keySet();for (String key:keyset){System.out.println(key+":"+map.get(key));}//使用entryset()方法System.out.println("\n========entrySet遍历===========");//Set<Map.Entry<String,String>> entries=map.entrySet();for(Map.Entry<String,String>entry: map.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}System.out.println("\n=====判断=====");System.out.println(map.containsKey("CN"));System.out.println(map.containsValue("俄罗斯"));
输出:
打印元素个数:4
{USA=美国, UK=英国, JP=日本, CN=中国}=========删除之后的个数=========
打印元素个数:3========keyset()遍历===========
USA:美国
UK:英国
CN:中国========entrySet遍历===========
USA:美国
UK:英国
CN:中国=====判断=====
true
false     }
}

2、Map集合的实现类

2.1、HashMap【重点】:

  • JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value。

新增一个学生类
为了确保key的不可重复性,所以需要重写Hashcode和equls方法

package com.jjl.Map;public class Student {private String name;private int stuNo;public Student() {}public Student(String name, int stuNo) {this.name = name;this.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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", stuNo=" + stuNo +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (!(o instanceof Student)) return false;Student student = (Student) o;if (stuNo != student.stuNo) return false;return name != null ? name.equals(student.name) : student.name == null;}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + stuNo;return result;}
}

主程序测试

package com.jjl.Map;import com.jjl.Set.Person;import java.util.HashMap;
import java.util.Map;/*
HashMap集合使用
存储结构:哈希表(数组+链表+红黑树)
使用KEY的Hashcode和equals作为重复依据*/
public class Demo02 {public static void main(String[] args) {//创建集合HashMap<Student,String> student=new HashMap<Student,String>();//添加元素Student s1=new Student("张一",100);Student s2=new Student("张二",200);Student s3=new Student("张三",300);student.put(s1,"北京");student.put(s2,"成都");student.put(s3,"重庆");//通过new的方法可以实现元素重复添加,如果想要new也加不进去,就需要重写Hashcode和equalsstudent.put(new Student("张三",300),"杭州");System.out.println("打印元素个数:"+student.size());System.out.println(student);System.out.println("\n==========删除之后的元素个数=======");student.remove(s1);System.out.println(student.size());System.out.println("\n========keySet遍历===========");for(Student key:student.keySet()){System.out.println(key+":"+student.get(key));}System.out.println("\n========Entry遍历===========");for(Map.Entry<Student,String> entry:student.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}//判断System.out.println("\n========判断key或者value是否存在===========");System.out.println(student.containsKey(s2));System.out.println(student.containsValue("成都"));}
}
输出:
打印元素个数:3
{Student{name='张二', stuNo=200}=成都, Student{name='张一', stuNo=100}=北京, Student{name='张三', stuNo=300}=杭州}==========删除之后的元素个数=======
2========keySet遍历===========
Student{name='张二', stuNo=200}:成都
Student{name='张三', stuNo=300}:杭州========Entry遍历===========
Student{name='张二', stuNo=200}:成都
Student{name='张三', stuNo=300}:杭州========判断key或者value是否存在===========
true
true

总结:

  • (1 )HashMap刚创建时,table是null,为了节省空间,当添加第一个元素是,table容量调整为16
  • (2)当元素个数大于阈值(16*8.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数。
  • (3)jdk1.8当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的提高执行效率
  • (4)jdk1.8 当链表长度小于6时,调整成链表
  • (5)jdk1.8以前,链表时头插入,jdk1.8以后时是尾插入

3、Hashtable:

  • .JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。
  • Properties :
    • Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。

4、TreeMap :

  • 实现了SortedMap接口(是Map的子接口),可以对key自动排序。
  • 要求元素实现Comparable接口,重写比较器

让元素类实现Comparable接口


主程序测试

package com.jjl.Map;
/*
TreeMap的使用*/import java.util.Map;
import java.util.TreeMap;public class Demo03 {public static void main(String[] args) {//新建集合TreeMap<Student, String> treemap=new TreeMap<>();Student s1=new Student("张一",100);Student s2=new Student("张二",200);Student s3=new Student("张三",300);treemap.put(s1,"北京");treemap.put(s2,"成都");treemap.put(s3,"重庆");System.out.println("打印元素个数:"+treemap.size());System.out.println(treemap);//遍历System.out.println("\n======entryset()遍历====");for (Student key : treemap.keySet()){System.out.println(key+":"+treemap.get(key));}System.out.println("\n======entryset()遍历====");for (Map.Entry<Student,String> entry:treemap.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}}
}
输出:
打印元素个数:3
{Student{name='张一', stuNo=100}=北京, Student{name='张二', stuNo=200}=成都, Student{name='张三', stuNo=300}=重庆}======entryset()遍历====
Student{name='张一', stuNo=100}:北京
Student{name='张二', stuNo=200}:成都
Student{name='张三', stuNo=300}:重庆======entryset()遍历====
Student{name='张一', stuNo=100}:北京
Student{name='张二', stuNo=200}:成都
Student{name='张三', stuNo=300}:重庆

当元素类不能实现Comparable接口时,可以使用定制比较

package com.jjl.Map;import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;public class Demo04 {public static void main(String[] args) {//新建集合(定制比较)TreeMap<Student, String> treemap=new TreeMap<>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {int n2= o1.getStuNo()-o2.getStuNo();return n2;}});Student s1=new Student("张一",100);Student s2=new Student("张二",200);Student s3=new Student("张三",300);treemap.put(s1,"北京");treemap.put(s2,"成都");treemap.put(s3,"重庆");System.out.println("打印元素个数:"+treemap.size());System.out.println(treemap);//遍历System.out.println("\n======entryset()遍历====");for (Student key : treemap.keySet()){System.out.println(key+":"+treemap.get(key));}System.out.println("\n======entryset()遍历====");for (Map.Entry<Student,String> entry:treemap.entrySet()){System.out.println(entry.getKey()+":"+entry.getValue());}}
}

5、Colletions工具类

  • 概念:集合工具类,定义了除了存取以外的集合常用方法。
  • 方法:
    • public static void reverse(List<?> list) //反转集合中元素的顺序
    • public static void shuffle(List<?> list) //随机重置集合元素的顺序
    • public static void sort(List< T > list) //升序排序(元素类型必须实现Comparable接口)
package com.jjl.Map;import java.lang.reflect.Array;
import java.util.*;/*
Colletions工具类的使用*/
public class Demo05 {public static void main(String[] args) {List<Integer> list=new ArrayList<>();list.add(20);list.add(5);list.add(12);list.add(30);list.add(6);//sort排序System.out.println("排序前:"+list.toString());Collections.sort(list);System.out.println("排序之后:"+list.toString());System.out.println("\n======binarySearch,二分查找======");//binarySearch,二分查找,如果找到了,则返回该元素的下标,如果没找到,则就返回一个负数int i=Collections.binarySearch(list,6);System.out.println(i);//copy复制//新建一个目标集合System.out.println("\n===========copy复制=====");List<Integer> dest=new ArrayList<>();//如果直接用“Collections.copy(dest,list);”复制元素,会报错,因为dest里面没有元素,默认大小为0,而list里面已经有5个元素了。//为了保证目标集合长度和源集合长的时一样的,则需要用for往目标集合里面添加一些占位元素。for (int k=0;k<list.size();k++){dest.add(0);}Collections.copy(dest,list);System.out.println(dest);//reverse反转Collections.reverse(list);System.out.println("\n反转之后:"+list);//shuffle打乱Collections.shuffle(list);System.out.println("\n打乱之后:"+list);//补充,list转成数组System.out.println("\n=========list转成数组============");Integer[] arr=list.toArray(new Integer[0]);System.out.println(arr.length);System.out.println(Arrays.toString(arr));System.out.println("\n=========数组(每个元素都是字符串)转成集合============");String[] name={"张一","张二","张三"};//通过这种方式转成的集合,它是一个受限集合,不能添加和删除元素List<String> list2=Arrays.asList(name);System.out.println(list2);System.out.println("\n=========数组(每个元素都是数字)转成集合============");//将基本类型数组转换为集合,需要修改为包装类Integer[] nums={100,200,300,400,500};List<Integer> list3=Arrays.asList(nums);System.out.println(list3);}
}
输出:
排序前:[20, 5, 12, 30, 6]
排序之后:[5, 6, 12, 20, 30]======binarySearch,二分查找======
1===========copy复制=====
[5, 6, 12, 20, 30]反转之后:[30, 20, 12, 6, 5]打乱之后:[12, 5, 20, 30, 6]=========list转成数组============
5
[12, 5, 20, 30, 6]=========数组(每个元素都是字符串)转成集合============
[张一, 张二, 张三]=========数组(每个元素都是数字)转成集合============
[100, 200, 300, 400, 500]

四、集合总结

  • 集合的概念:

    • 对象的容器,和数组类似,定义了对多个对象进行操作的常用方法。
  • List集合:
    • 有序、有下标、元素可以重复。(ArrayList、LinkedList、Vector>
  • Set集合:
    • 无序、无下标、元素不可重复。(HashSet、TreeSet)
  • Map集合:
    • 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
  • Collections:
    • 集合工具类,定义了除了存取以外的集合常用方法。

java学习之路8——Java集合框架相关推荐

  1. Java学习之路-day-09 ArrayList集合

    Java ArrayList集合 每日一句 1. ArrayList 1.1 ArrayList类概述 1.2 ArrayList类常用方法 1.3 ArrayList存储字符串并遍历 1.4 Arr ...

  2. Java学习之路4——Java数组

    教学视频来源链接 一.数组概述 数组是相同类型数据的有序集合. 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问 ...

  3. 小W的Java学习之路:java基础(四)-数组

    1.为什么要有数组? 数组可以存储相同类型的多个数据,把多个数据放在一个数组中方便使用如果只需要定义一个变量需要数组么?不需要 2.数组的定义 动态初始化:数据类型[] 数组名 = new 数据类型[ ...

  4. java学习之路目录(已完结)

    java学习之路目录(持续更新中-) 第一阶段 javaSE(完结) 序号 标题 内容 001 java初识 java语言特点.体系结构.运行机制 002 java SE基础语法 注释.关键字.变量. ...

  5. Java学习之路——接口

    Java学习之路--接口 概述 总所周知,我们是父母的孩子.我们的身上既继承了爸爸的基因也继承了妈妈的基因.这就是多继承. 然而在 Java 程序中,是不支持多继承的.Java 仅仅支持单继承.但是接 ...

  6. 我的Java学习之路2009-11-17

    -------------------------------2009年3月19日开始----------------------------- 下载JDK Myeclipse Netbeans JB ...

  7. JAVA学习之路:不走弯路,就是捷径(一)

      0.引言 在ChinaITLAB导师制辅导中,笔者发现问得最多的问题莫过于"如何学习编程?JAVA该如何学习?".类似的问题回答多了,难免会感觉厌烦,就萌生了写下本文的想法.到 ...

  8. java学习之路之javaSE基础1

    <h2>java学习之路之javaSE基础1</h2> <div> ###01.01_计算机基础知识(计算机概述)(了解) * A:什么是计算机?计算机在生活中的应 ...

  9. 1024 java学习之路。

    1024程序员节啦~ 从今天开始记录java学习之路. 从自开始接触java到现在快半年了从2020年的2月份到现在的10月份,中间也因为写毕设推迟了一些时间.算上来应该有半年了.半年中还是收获很多哒 ...

最新文章

  1. 后台运行定位,音频,网络电话
  2. windows下卸载oracle11g
  3. ++库 照片风格转换风格_怦然心动的小清新风格照片拍摄,这四点很关键
  4. Google protobuf使用技巧和经验
  5. iOS开发ARC内存管理技术要点
  6. 区块链的那些事,你知道和不知道的都在这里!
  7. python两个数组合并、找出中位数_leetcode刷题记录-找出这两个有序数组的中位数(python版本)...
  8. C++STL中的priority——queue
  9. perl中的sleep函数
  10. 360搜索核心算法,被K后如何恢复?
  11. 链表排序python
  12. steam反作弊服务器未响应,受反作弊影响 Steam Deck暂无法运行部分主流游戏
  13. october cms_October CMS静态页面入门
  14. 树莓派上搭建rtsp流媒体服务器
  15. 基于javaweb个人网站论坛的设计与实现(源码、论文、毕业设计、数据库文件)
  16. PP-ShiTu: A Practical Lightweight Image Recognition System
  17. 为什么我们需要独立的B2C网店
  18. 解读Linux零拷贝之mmap
  19. OD-火星文计算(Python)
  20. vue es6转es5 保证浏览器兼容性

热门文章

  1. The Controller Placement Problem in Software Defined Networking
  2. 代码覆盖率工具BullseyeCoverage研究
  3. 贝叶斯的路——概率论迷思
  4. 微盟股价逆变的背后: 经济寒冬已至,SaaS产业如何破局?
  5. C# 按Button弹出新的窗体 Show()方法 和 ShowDialog()方法
  6. java代码json_JSON 解析(java代码)
  7. android cs,CS 1.6移植安卓手机:附安装教程
  8. SCIE与SCI差别是啥?
  9. 租房管理系统 php,php出租房数据管理及搜索页面
  10. win10找不到打印机_新版Windows 10的外设Bug:重启后找不到USB打印机端口