Java集合讲解

 

【集合概念】
1.类中属性类型相同,意义与作用也相同,就可以放到集合中
2.数组的长度是固定的,集合的长度或者容量在使用时可以动态扩展的
3.Collection接口和Map接口
4.Collection:序列List(元素排列有序可重复,实现类ArrayList,数组序列) 队列Queue(元素排列有序可重复,实现类LinkedList,链表也是List实现类) 集Set(无序不可重复 HashSet哈希集)
5.Map(实现类:HashMap 哈希表)内部类 Entry(键值对) 实例<Key,Value>

JAVA集合框架体系结构:Collection与Map是两个根接口。
Collection接口:内部存储的是一个个独立的对象。包含:
1、List接口:序列,存储元素排列有序且可重复。实现类:ArrayList,数组序列。实现类:LinkedList,链表。
2、Queue接口:队列,存储元素排列有序且可重复。实现类:LinkedList,链表。
3、Set接口:集,存储元素无序且不可重复。实现类:HashSet,哈希集。
Map接口:内部以<Key,Value>两个对象(任意类型)为一个映射去存储数据,这一个映射就是Entry类(Map的内部类)的实例。包括:实现类:HashMap,哈希表。
 

 

 

Collection(接口)
  - List(接口)(特点:有序,可重复)
    - ArrayList(实现类)
    - LinkedList(实现类)
  - Query(接口)(特点:有序,可重复)
    - LinkedList(实现类)
  - Set(接口)(特点:无序,不可重复)
    - HashSet(实现类)
Map(接口)(特点:Entry(Key,Value) -- 键值对:)注:Entry是Map的内部类
  - HashMap(实现类)

Collection接口是List、Set、Queue接口的父接口
Collection接口定义了可用于操作List、Set和Queue的方法--增删改查
List接口及其实现类--ArrayList
List是元素有序并且可以重复的集合,被称为序列。
List可以精确的控制每个元素的插入位置,或删除某个位置元素
List有add()插入方法和get()获取方法
ArrayList--数组序列,是List的一个重要实现类
ArrayList底层是由数组实现的,这也是其名字的由来

List是接口,所以在构造方法中不能直接实例化,而通过ArrayList()实例化。<br>
例:public List coursesToSelect = new ArrayList();<br>
调用Add()方法添加到List中。有两种方法:<br>
方法1:直接添加,例:CoursesToSelect.add(cr1);<br>
方法2:可以指定添加的位置,例:CoursesToSelect.add(0,cr1);<br>
使用get()方法取出一个对象,当一个对象被添加到集合中去的时候,它会被忽略掉类型,而都变成Object类型,取出时需要类型转换。<br>
例:Course temp = (Course)coursesToSelect.get(0);<br>
如果添加到List中的长度大于他目前的长度,则系统会出现异常,即数组下表越界异常<br>
addAll(Arrays.asList(数组名))的用法是:
1.创建一个对象数组并实例化。Course []course={new course(),new course()};
2.容器对象.addAll(Arrays.asList(对象数组名));
3.获取元素,定义一个Course对象来存储容器对象.get(index)的值 要类型转换。
Course temp=(Course)(CourseToSelect.get(index));
4.输出获取的值,System.out.println(temp.属性+temp.属性2);

list中还有addAll(List list)
就是将一个List里面的元素一股脑的全都加进去,妙哉妙哉
一般定义一个数组,如何把一个数组转换成List? 调用方法Arrays.asList(Object[] obs);//可以将一个数组转换为一个List,然后可以将这个元素传进addAll()里面
当然还有addAll(index,List list)方法
removeAll直接传入一个list,同理
记得取出东西之后,要类型强转哦!!!因为取出来都是Object的。
向List中添加元素的几种方法:
新建List类
public List courseToSelect;
初始化List类
public ListTest()
{
this.courseToSelect=new ArrayList();
}
向List中添加数据
method_1
courseToSelect.add(对象1);
method_2
courseToSelect.add(位置,对象2);
method_3
courseToSelect.addAll(Arrays.asList(数组_对象3));
method_4
courseToSelect.addAll(位置,Arrays.asList(数组_对象4));
获取
Course temp=(Course)courseToSelect.get(位置);

List可以精确的控制每个元素的插入位置,多删除某个位置的元素
- ArrayList底层是由数组实现

list.add(对象)把一个对象添加到另一个集合的队尾位置
list.add(index, 对象) 把一个集合添加到另一个集合的指定位置
list.addAll(集合对象) 把一个集合添加到另一个集合的队尾位置
list.addAll(index, 集合对象) 把一个集合添加到另一个集合的指定位置
Arrays.asList(数组) 把一个数组转换成List集合

以下三种方法都是用来取出List中元素的方法:<br>
-----for循环-----<br>
public void testGet(){<br>
int size=coursesToSelect.size();<br>
for(int i=0;i<size;i++){<br>
Course cr=(Course) coursesToSelect.get(i);<br>
System.out.println("取出的课程:"+cr.getId()+":"+cr.getName());<br>
}<br>
}<br>
-----迭代器-----<br>
Iterator是一个接口,依赖于集合存在的,本身不具备存储功能<br>
Iterator it=courseToSelect.iterator();<br>
while(it.hasNext()){<br>
Course cr=(Course) it.next();<br>
System.out.println("课程:" + cr.id + ":" + cr.name);<br>
}<br>
<br>
-----for each(增强for循环)-----<br>
<br>
凡是继承了Iterable接口的类所生成的对象都可以用for/each循环<br>
<br>
for(Object obj:coursesToSelect){//遍历集合中的每一个元素,作为每一个Object变量<br>
Course cr=(Course) obj;<br>
System.out.println("课程:" + cr.id + ":" + cr.name);<br>
}
 

package collection;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
 
/**
 * @author Xinny
 * @create 2021-09-29 11:48 上午
 */
 
public class ListTest {
 
    //用于存放备选课程的list
    public List coursesToSelect;
 
    public ListTest() {
        this.coursesToSelect = new ArrayList();
 
    }
 
    //添加课程
    public void testInsert() {
        //创建课程对象
        Course c1 = new Course("1", "C++");
        coursesToSelect.add(c1);
        Course temp = (Course) coursesToSelect.get(0);
        System.out.println("add" + temp.id + ":" + temp.name);
        Course c2 = new Course("2", "Python");
        coursesToSelect.add(0, c2);
        Course temp2 = (Course) coursesToSelect.get(0);
        System.out.println("添加了课程:" + temp2.id + ":" + temp2.name);
 
 
        Course[] course = {
                new Course("3", "Java"),
                new Course("4", "Vue")};
        coursesToSelect.addAll(Arrays.asList(course));
        Course temp3 = (Course) coursesToSelect.get(2);
        Course temp4 = (Course) coursesToSelect.get(3);
        System.out.println("add two course:" + temp3.id + ":" + temp3.name + ":" + temp4.id + ":" + temp4.name);
        Course[] course2 = {new Course("5", "高数"), new Course("6", "大英")};
 
 
        coursesToSelect.addAll(2, Arrays.asList(course2));
        Course temp5 = (Course) coursesToSelect.get(2);
        Course temp6 = (Course) coursesToSelect.get(3);
        System.out.println("add two course:" + temp5.id + ":" + temp5.name + ":" + temp6.id + ":" + temp6.name);
 
 
    }
 
    public void testGet() {
        int size = coursesToSelect.size();
        System.out.println("now have:");
        for (int i = 0; i < size; i++) {
            Course cr = (Course) coursesToSelect.get(i);
            System.out.println("course:" + cr.id + ":" + cr.name);
        }
    }
 
    //通过迭代器来遍历list
 
    public void testIterator() {
        Iterator it = coursesToSelect.iterator();
        System.out.println("now have:");
        while (it.hasNext()) {
            Course cr = (Course) it.next();
            System.out.println("course:" + cr.id + ":" + cr.name);
        }
    }
 
 
    //通过for each方法访问集合元素
    public void testForEach() {
        System.out.println("now have (for each):");
        for (Object obj : coursesToSelect) {
            Course cr = (Course) obj;
            System.out.println("course: " + cr.id + ":" + cr.name);
        }
    }
 
    //修改list中的元素
 
    public void testModify(){
        coursesToSelect.set(4,new Course("7","编译原理"));
    }
 
 
 
    //删除list中的元素
 
    public void testDelete(){
        //方法1
        /**Course cr=(Course)coursesToSelect.get(4);
         System.out.println("我是课程:"+cr.id+";"+cr.name+",我即将被删除");
         coursesToSelect.remove(cr);*/
 
        //方法2
        /**System.out.println("即将删除4位置上的课程");
         coursesToSelect.remove(4);
         System.out.println("成功删除课程!");*/
 
        //方法3
        System.out.println("delete index=4 and index = 5 course");
        Course[] courses={(Course)coursesToSelect.get(4),(Course)coursesToSelect.get(5)};
        coursesToSelect.removeAll(Arrays.asList(courses));//将数组转换为集合
        System.out.println("delete success!");
        testForEach();
 
    }
 
 
    public static void main(String[] args) {
        ListTest it=new ListTest();
        it.testInsert();
        it.testGet();
        it.testIterator();
        it.testForEach();
        it.testModify();
        it.testForEach();
        it.testDelete();
 
 
    }
}

 73fc3d65cb9241bfac74ae677650a9c6.png

 

Set接口及其实现类——HashSet

Set是元素无序并且不可以重复的集合,被称为集;

HashSet——哈希集,是Set的一个重要实现类。

1、Set没有像List中set()方法一样就修改,因为List是有序的,可以指定位置,而Set是无序的。

2、查询遍历时,Set不能用get()方法去获取,因为无序没有指定索引ID,但可以使用foreach和iterator来遍历,但是每次遍历出来可能顺序都不一样,还是因为无序造成的。

3、Set中的size(),add(),addAll(),remove(),removeAll()与List类似。

4、Set还可以添加null;无序演示(如图)
 

4f7c5e97aecc4ff6b693f5583e1185a6.png

 

1、List<>()这是一个有序序列。因为List是一个接口,并不能实例化。因此我们需要将用Arraylist来实现。
2、Arraylist是一个数组序列也是list的一个重要的实现类,用来执行list的增删改查等。
List<>() a=new Arraylist<>(); 或者通过构造参数的形式实现。
3、在现实开发当中,课程等成员变量是私有化的,需要用get()和set()方法。
4、对象被存入集合都变成object类型了 取出时需要类型强转。但在List<类型>()声明了类型的就只能存入该类型的数据,并且提取时也只会是该类型,不用强转。
例:Course temp = (Course)coursesToSelect.get(0);//强转
5、调用Add()方法添加到List中。有两种方法:
a) 直接添加,例:CoursesToSelect.add(cr1);
b) 可以指定添加的位置,例:CoursesToSelect.add(0,cr1);
6、如果添加到List中的长度大于他目前的长度,则系统会出现异常,即数组下表越界异常
7、list中还有addAll(List list)
就是将一个List里面的元素一股脑的全都加进去
一般定义一个数组,如何把一个数组转换成List? 调用方法Arrays.asList(Object[] obs);//可以将一个数组转换为一个List,然后可以将这个元素传进addAll()里面
当然还有addAll(index,List list)方法
8、迭代器只是用来遍历集合中的元素,本身不具备任何存储元素的功能,换而言之,迭代器是依赖于某个集合而存在的,本身不能独立存在。
读取元素三种方法:
a)for()
b)Iterator是一个接口,依赖于集合存在的
Iterator it=courseToSelect.iterator();
while(it.hasNext()){} //迭代
c)foreach
9、使用set(index,Object element)修改元素,index表示索引位置,element表示新对象。

3eed142d93f44327a6837a467cba06e2.png

Map接口
1. Map接口提供了一中映射关系,其中的元素是键值对(key-value)的形式存储的,能够实现根据Key快速查找value。Key-value可以是任何对象,是以Entry类型的对象实例存在的。
2.Key是不可以重复的,Value是可以重复的。Key-value都可以为null,不过只能有一个key是null。
3.map支持泛型,Map<K,V>
4.每个键最多只能映射到一个值
5.Map接口提供了分别返回key值集合、value值集合以及Entry(键值对)集合的方法
6.通过put<K key,V value>,remove<Object key>操作数据
7.HashMap中的Entry对象是无序排列的,HashMap是Map的一个重要实现类,也是最常用的,基于哈希表是实现
 

aa04c23ace004ca98a156c474cd3cfdf.png

 

Map接口提供了分别返回key值集合、value值集合以及Entry(键值对)集合的方法
Map支持泛型,形式如:Map<K,V>
HashMap类
HashMap是Map中的一个重要的实现类,也是最常用的,给予哈希表实现
HashMap中的Entry对象是无序排列的
Key值和Value值都可以为Null,但是一个HashMap只能有一个key值为Null的映射(key值不可重复)

student.get(ID)是采用Map的get()方法,检测是否存在值为ID的学生,如果没有,则返回null.

keySet()方法,返回所有键的Set集合。
取得Map的容量可用size()方法。

keyset()返回Map中所有的key以集合的形式可用Set集合接收,HashMap当中的映射是无序的。
students.get(ID)是采用Map的get()方法

List:类似数组,有从0开始int类型的标记,可存储任意对象,存储对象可重复

Set:可存储任意对象,存储对象不可重复

Map:存储的单位对象是一组键值对entry,其中key不可重复,value可以重复,key和value都可以是任意对象
 

HashMap类型对象中的get(key)方法通过输入参数key值返回对应的value值,如果映射不存在,则返回null。
put(key,value)方法则是建立对应的映射关系。

 Map增删改查: 增:map的put(key,value)方法添加。 查:1.利用keyset()方法获得Map中key的集合,再遍历key的集合,利用Map的get(key)方法得到key对应的value值。 2.利用EntrySet方法获取May中Entry对象集:然后用foreach遍历集,再用Entry集的getkay()和getvalue()方法得到每一个key值和value值。 删:remove(object key) 改:put(原有的key,新的value) 通过entrySet可以返回Map中的所有键值对 Set<Entry<String,Student>>entrySet = students.entrySet();
 

遍历  keySet  返回是key
     entrySet  返回是键值对
修改 put方法  只需将value中的name更改
添加  put方法
删除   remove(key)

 关于Map:
1.初始化变量
Map<String,Student>students = new HashMap<String,Student>()
//初始化key值为String,存放的数据类型为student的students集合
2.put()增加对象
Student newStu = new Student(ID,name);
students.put(ID,newStudent);//以ID作为key值
3.查找对象
(1)Set<String>keySet = students.keySet();
for(String stuId:keySet){
Student st =students.get(stuId);
}//先用keySet()获取所有的key,再遍历获取每一个对象
(2)Set<Entry<String,Student>>entrySet = students.entrySet();//由于每个键值对都以entry类型存放,yongentrySet()方法获取所有键值对
for(Entry<String,Student>entry:entrySet) {//遍历获取键值对
entry.getKey();//获取key
entry.getValue();//获取value
}
4.删除
students.remove(ID);//根据key的值删除
5.修改
Student stu = students.get(ID);
Student newStudent =new Student(ID,newname);
students.put(ID,newStudent);
/*Map中没有直接修改的方法,所以采用先找出对象,然后不修改key值,只修改value的方法进行修改*/
 

 

 

"=="和equals()的区别:
1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
 

 

1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
7f460729400645848cdb8059848f2797.png

 ist 与 set 中contain()方法调用机制:
list 中的contain()方法是拿到list中的每个对象来调用Object类中的equals()方法
Set  中的contain()方法是拿到list中的每个元素来先调用hashcode()方法来返回哈希码值,当哈希码的值相等时,再调用equals()方法,当比较的元素此时也相同时,才会返回true。因此调用Set中的contain()方法时,需要对hashcode()方法及equals()方法进行重写。
 

indexOf()方法与lastIndexOf()方法实现原理:
1、遍历调用每个元素的equals()方法,如果返回true则将次元素的索引返回;
2、如果有多个相同元素,则只返回第一个元素的索引;
3、lastIndexOf()方法则从最后一个元素开始遍历;

a582a24391e6450f8720fcfc8cbb8c86.png

 

 

Collection集合中的公用方法
①.cointains方法--------返回值为boolean,测试集合中是否存在某个元素
②.indexof方法----------测试集合中某个元素第一次出现的的位置。如果元素不存在返回-1
③.lastIndexof方法------测试集合中某个元素最后一次出现的位置。如果元素不存在返回-1
⑤.size方法-------------测试集合的容量大小
⑥.在Map中,用containsKey()方法来判断是否包含某个key值。返回值为true,则包含。
⑦.在Map中,用containsValue()方法来判断是否包含某个value值。

集合的indexof方法去找元素的位置,数组可以直接转成集合,修改也有直接修改的方法。
5f1e9b454b62488e9cfcc56b1a651ae9.png

Map映射表
一、判断是否包含某个Key值:containsKey()
二、判断是否包含某个Value值:containsValue()
1、同样是以每一个元素的value值的equals方法进行比较,所以需要重写value类的equals()方法来进行属性(某个)比较

关于Student的hashCode和equals 方法重写:

没有重写之前是比较的新建对象所在的内存空间 而重写之后则是比较两个类对象是否相同
afa36fae3f5447c4bb798a9d95c170ad.png

 

 

 

/**
 * 通过调用sort方法对String类型的元素进行排序
 */
public void testSort2(){
	List<String> StringList=new ArrayList<String>();
	//定义存储随机字符的字符串
	String str="1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	//创建Random的实例,用于生成随机数
	Random random=new Random();
	//循环10次,生成10个随机长度的字符串
	for(int i=0;i<10;i++){	
		//创建一个StringBuilder类的字符串,方便随意的追加、修改
		//注意要放在for循环内,才能每生成一个字符串并输出后,归零
		StringBuilder sb=new StringBuilder();
		//规定字符串的长度为10以内的随机数
		int length=random.nextInt(10);
		for(int j=0;j<length;j++){
			//获取字符串str中的任意一个字符,然后追加进sb字符串
			int number=random.nextInt(str.length());
			sb.append(str.charAt(number));
		}
		//生成一个字符串后存储进集合中,并输出
		StringList.add(sb.toString());
		System.out.println("生成随机字符串:"+sb.toString());
		
	}
	System.out.println("---------排序前--------");
	for (String string : StringList) {
		System.out.println("元素:"+string);
	}
	Collections.sort(StringList);
	System.out.println("--------排序后---------");
	for (String string : StringList) {
		System.out.println("元素:"+string);
	}
}

 

 

ollections工具类---sort()

注意点:不能使用自定义的,若要使用则要实现Comparable接口。

3a8c6894df609092474948c03148c1df.png

 

 

sort()

f2cd6120b18027f4cb0eb3e85ae97d89.png

一、compareable 是默认比较规则, comparator是临时比较规则
1.Comparable接口------可比较的
实现该接口表示:这个类的实例可以比较大小,可以进行自然排序
定义了默认的比较规则
其实现类需实现compareTo()方法
comparaTo()方法返回正数表示大,负数表示小,0表示相等
2.Comparator接口-----比较工具接口
用于定义临时比较规则,而不是默认比较规则
其实现类需要实现compare()方法
Comparator和Comparable都是Java集合框架的成员

compareable 需要实现compare to方法, comparator需要实现 compare方法

三、Java集合框架:
Collection接口,Map接口,Collections工具类,Comparable接口,Comparator接口

Java集合框架的主要成员

8c8af0792ced426c9b96d57283a88cb9.png

 

 

主类第四段:
Collections.sort(array);
 
		//判断1玩家的最大手牌
		ArrayList<String> array1=new ArrayList<String>();
		array1.add(al.get(0));
		array1.add(al.get(2));
		Collections.sort(array1);
		//判断1玩家的最大手牌
		ArrayList<String> array2=new ArrayList<String>();
		array2.add(al.get(1));
		array2.add(al.get(3));
		Collections.sort(array2);
		//输出玩家1的最大手牌
		for(int i=0;i<ch.length;i++){
			if(array1.get(1).equals(ch[i])){
				System.out.println("玩家:"+alwj.get(0).name+"的最大手牌为:"+str[i]);
			}
		}
		//输出玩家2的最大手牌
		for(int i=0;i<ch.length;i++){
			if(array2.get(1).equals(ch[i])){
				System.out.println("玩家:"+alwj.get(1).name+"的最大手牌为:"+str[i]);
			}
		}
		//判断玩家谁获胜
		if(array.get(3).equals(al.get(0))||array.get(3).equals(al.get(2))){
			System.out.println("*********玩家:"+alwj.get(0).name+"获胜!**********");
		}else{
			System.out.println("*********玩家:"+alwj.get(1).name+"获胜!**********");
		}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值