Java学习笔记(二) 集合

集合

一:集合概念

对象的容器,实现了对对象常用的方法,类似数组功能

二:和数组的区别

  • 数组长度固定,集合长度不固定
  • 数组可以存储基本类型和引用类型,集合只能存储引用类型

位置:java.util.*;

Collection体系集合

Collection父接口

特点:代表一组任意类型的对象,无效、无下标、不能重复

方法

  • boolean add(Object obj)//添加一个对象
  • boolean addAll(Collection c)//将一个集合中的所有对象添加到此集合中
  • void clear()//清空此集合中的所有对象
  • boolean contains(Object o)//检测此集合中是否包含o对象
  • boolean equals(Object o)//比较此集合是否与指定对象相等
  • boolean isEmpty() //判断此集合是否为空
  • boolean remove(Object o)//在此集合中移除o对象
  • int size() //返回此集合中的元素个数
  • Object[] toArray();//将此集合转换成数组
//创建集合
//Collection 是接口,不能被实例化
Collection c=new ArrayList<>();//父类调用指向子类对象
//添加元素
c.add("苹果");
c.add("丝瓜");
c.add("草莓");
System.out.println(c.size());//打印个数 3
System.out.println(c);// [苹果,丝瓜,草莓]
//删除
c.remove("丝瓜");
System.out.println(c.size());//打印个数 2
//清空 c.clear();

//遍历元素(重点)
for(Object object : c){
   System.out.println(object); //打印每一个对象
}

//法二 使用迭代器,专门用来遍历集合
Iterator it = c.iterator();
//该迭代器有三个方法 
//hasNext();有没有下一个元素
//next(); 获取下一个元素
//remove();删除当前元素

while(it.hasNext()){
   Object ob= it.next();
    System.out.println(ob);
}
//迭代过程中是不能使用 collection的方法改变元素
//只能用 Iterator 的remove方法 删除元素

//判断
c.contains("丝瓜"); 
c.isEmpty();

保存学生信息

//Student 类中 有name  age属性

//新建Collection对象
Collection c = new ArrayList<>();
//添加数据
Student s1 = new Student("zhangsan",18);
Student s2 = new Student("zhang",19);
Student s3 = new Student("lisan",22);

c.add(s1);
c.add(s2);
c.add(s3);
//打印输出结果
//删除
c.remove(s1);
//clear方法只是把对象从集合里删除,对象还是存在的

//遍历1
for(Object ob :c){
    Student s=(Student)ob;//强转类型
    System.out.println(s.toString());
}
//遍历2
Iterator it = c.iterator();
while(it.hasNext){
    Student s = (Student)it.next();
    System.out.println(s.toString());
}
//判断
c.contains(s1);//true;

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之间的集合元素
/*
有下标,可重复
*/
//创建集合
List list=new ArrayList<>();
//添加元素
list.add("苹果");
list.add("水蜜桃");
list.add("香蕉");
list.add(0,"橘子");
System.out.println(list.toString());
//[橘子,苹果,水蜜桃,香蕉]

//删除元素
list.remove("苹果");
//删除第一个元素
list.remove(0);

//遍历
//for
for(int i=0;i<list.size();i++){
    Object ob=list.get(i);
}

//增强for
for(Object ob:list){
   // ob;
}
//迭代器
Iterator it = list.iterator();

while(it.hasNext()){
    //
}
//列表迭代器 ListIterator
/*
和Iterator区别
可以向前向后遍历,添加删除
*/
ListIterator lit = list.listIterator();
//从前往后
while(lit.hasNext()){
    //下标
    System.out.println(lit.nextIndex());
    //打印内容
    System.out.println(lit.next());
}
//从后往前
while(lit.hasPrevious()){
    lit.previousIndex();
    lit.previous();
}

//判断
list.contains("");
list.isEmpty();

//获取位置
list.indexOf("苹果");

添加数字(基本)类型(会自动装箱)

list.add(20);

list.add(30);

list.remove(20);//会报错,没有20的下标,

想删除20 :

list.remove(new Integer(20));

或者

list.remove((Object)20)

//补充方法 subList 返回子集合 含头不含尾
List sublist = list.subList(1,3);//从下标1到下标2

List实现类

  • ArrayList【重点】

    • 数组结构实现,查询快、增删慢
    • JDK1.2版本,运行效率快、线程不安全
  • Vector:

    • 数组结构实现,查询快,增删慢
    • JDK1.0版本,效率慢,线程安全
  • LinkedList:

    • 链表结构实现,增删快,查询慢

ArrayList 的使用

有序有下标可重复

存储结构是数组,查找遍历速度快,增删速度慢

ArrayList arrayList = new ArrayList<>();

//添加
Student s1=new Student("liudehua",22);
Student s2=new Student("guofucheng",23);
Student s3=new Student("liangchaowei",18);

arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
arrayList.add(s4);

//删除
arrayList.remove(s1);//删除s1
arrayList.remove(new Student("liudehua",22));//删不掉
//需要删除内容相同的对象
//要重写Student类的equals方法

//遍历 重点
//使用迭代器
Iterator it=arrayList.iterator();
while(it.hasNext()){
    Student s=(Student)it.next();
    System.out.println(s.toString());
}
//列表迭代器
ListIterator lit=arrayList.listIterator();
while(lit.hasNext()){
    Student s=(Student)lit.next();
    System.out.println(s.toString());
}
//判断
contains();
isEmpty();
//查找
indexOf();
//分析源码可知

没有添加任何元素,空间为0
添加一个元素后,空间开阔为10
添加第十一个元素后,空间开阔为15

Vertor

数组结构实现,查询快、增删慢

JDK1.0版本,运行效率慢、线程安全

//创建集合
Vector vector = new Vector<>();

//添加元素 
vector.add();
//删除
vector.remove();
vector.clear();
//遍历 使用枚举器
Enumeration en = vector.elements();
while(en.hasMoreElements()){
    en.nextElement();
}
//判断
vector.contains();
//补充
firsetElements

LinkedList

链表结构实现,增删快,查询慢

双向链表

//创建集合
LinkedList linkedList = new LinkedList<>();
//添加元素
linkedList.add();
//元素个数
linkedList.size();
//删除元素
linkedList.remove();
linkedList.clear();
//遍历元素

for(int i=0;i<linkedList.size();i++){
    linkedList.get(i);
}
//增强for
for(Object object : linkedList){
    object;
}
//迭代器
Iterator it = linkedList.iterator();
while(it.hasNext()){
    it.next();
}
//迭代器2
ListIterator lit =linkedList.listIterator();
//判断元素
linkedList.contains();
linkedList.isEmpty();
//获取 对象在链表中的下标
linkedList.indexOf();

泛型

  • JDK1.5的新特性,本质是参数化类型,把类型作为参数传递
  • 常见形式有泛型类、泛型接口、泛型方法
  • 语法 <T,…> T 称为类型占位符,表示一种引用类型
  • 好处
    • 提高代码的复用性
    • 防止类型转换异常,提高代码的安全性
//泛型类  在类名后面 <T>
// T 是类型占位符,是一种引用类型,如果多个用逗号隔开
public class MyGeneric<T> {
    //使用泛型T
    //1.创建变量
    T t;
    
    //作为方法参数
    public void show(T t){
        //不能实例化,可以创建变量
        System.out.println(t);
    }
    //泛型作为方法的返回值
    public T getT(){
	   return t;
    }
}

使用泛型类

public class TestGeneric{
    public static void main(String[] args){
        //使用泛型类创建对象
        //1.泛型只能是引用类型
        //2.不同泛型类型对象之间不能相互复制
        MyGeneric<String> myGeneric = new Mygeneric<String>();
        myGeneric.t="hahaha";
        myGeneric.show("123");
        String string = myGeneric.getT();
        
        
        MyGeneric<Integer> myGeneric2 = new MyGeneric<Integer>();
        myGeneric2.t=100;
        myGeneric2.show(200);
        Integer integer = myGeneric2.getT();
        
        //使用泛型接口
        MyInterfaceImp imp1=new MyInterfaceImp();
        imp1.server("xxx");
        
        MyInterfaceImp2 imp2=new MyInterfaceImp2<>();
        imp2.server(1000);
    }
}

泛型接口

/*
泛型接口
语法 接口名<T>
注意:不能泛型静态常量
*/
public interface MyInterFace<T>{
	String name = "zhangsan";
    T server(T t);
}

实现类

//方式一 已经确定类型
public class MyInterfaceImp implements MyInterface<String> {
    public String server(String t){
        System.out.println(t);
        return t;
    }
}

//方式2 不确定类型
public class MyInterfaceImp2<T> implements MyInterface<T> {
    public T server(T t){
        System.out.println(t);
        return t;
    }
}

泛型方法

/*
泛型方法
语法 <T>方法的返回值类型
*/

public class MyGenericMethod{
	//泛型方法
    public <T> T show(T t){
		System.out.println("泛型方法");
        return t;
    }
}

测试泛型方法

MyGenericMethod my=new MyGenericMethod();
//类型由传递值的类型决定
my.show("lalalala");

my.show(200);

my.show(3.14);

泛型集合

  • 概念:参数化类型,类型安全的集合,强调集合元素的类型必须一致
  • 特点
    • 编译时即可检查,而非运行时抛出异常
    • 访问时,不必类型转换(拆箱)
    • 不同泛型之间引用不能相互赋值,泛型不存在多态
ArrayList<String> arrayList=new ArrayList<String>();
//这样做限制了 类型
arrayList.add("sss");

arrayList.add(123);//会报错

ArrayList<Student> arrayList2=new ArrayList<Student>();
//只能添加Student类型数据


//泛型不同的对象不能相互赋值

set

  • 特点:无序、无下标、元素不可重复
  • 方法:全部继承自Collection中的方法

set接口实现

/*
测试Set接口的使用
没有顺序,没有下标,不能重复
*/
import java.util.Set;

public class Demo1{
    public static void main(String[] args){
	//创建集合
        Set<String> set =new  HashSet<>();
        //添加
        set.add("sss");
        
        //数据个数
        set.size();
        //删除
        set.remove("sss");
        //清空
        set.clear();
        
        //遍历
       // 增强for
        for(String string : set)
			System.out.println(string);
        //迭代器
        Iterator<String> it=set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

set实现类

  • HashSet(重点)

    • 基于HashCode计算元素存放位置
    • 当存入元素的哈希码相同时,会调用equals进行确认,如结果是true,则拒绝后者存入
  • TreeSet

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

HashSet集合的使用

/*
存储结构:哈希表(数组+链表+红黑树)
无序的,和添加顺序无关
不能重复

存储过程:
1)根据hashcode计算保存的位置,如果此位置为空,则之间保存,如果不为空则执行第二步
2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
*/

//创建集合
HashSet<String> hashSet = new HashSet<>();

//添加元素
hashSet.add("zhangsan");
hashSet.add("lisi");
hashSet.add("wangwu");
hashSet.add("zhaoliu");

//删除
hashSet.remove("lisi");
//清空
hashSet.clear();
//增强for遍历
for(String string : hashSet){
	System.out.println(string.toString());
}
//迭代器遍历
Iterator it = hashSet.iterator();
while(it.hasNext()){
	System.out.println(it.next().toString());
}

//判断
hashSet.contains("lisi");
//判断是否为空
hashSet.isEmpty();

//元素个数
hashSet.size();

Person p1 = new Person(“zhangsan”,23);

persons.add(p1);

//即使年龄和姓名相同,但是是一个新的对象

//默认会添加到hashset集合中

persons.add(new Person(“zhangsan”,23));

//为了使相同名字和年龄的对象不能重复添加

//1.重写hashCode方法

//若名字和年龄一样,则返回的哈希值也一样
//会形成链表加入
public int hashCode(){
    int n1=this.name.hashCode();
    int n2=this.age;
    
    return n1+n2;
}
//2.还需要重写equals
public boolean equals(Object obj){
	if(obj==null){
		return fasle;
    }
    if(this==obj){
        return true;
    }
    //类型是 Person类
    if(obj instanceof Person){
        //强制类型转换
        Person p =(Person)obj;
        //判断属性
        if(this.name.equals(p.getName()) && this.age=p.getAge()){
		    return true;
        }
    }
    return fasle;
}

TreeSet集合的使用

/*
存储结构:红黑树
*/

TreeSet<String> treeSet = new TreeSet<>();

//添加元素
treeSet.add("xyz");
treeSet.add("abc");
treeSet.add("hello");

//没有重复

//元素个数
treeSet.size();
//删除
treeSet.remove("xyz");

//遍历
for(String string: treeSet){
	string;
}
Iterator it = treeSet.iterator();
while(it.hasNext()){
	it.next();
}
//判断
treeSet.contains();

补充:

用Person类 添加到TreeSet类 会出错

需要创建一个接口,给定要比较的是什么

给定比较的规则

要求:元素必须实现Comparable接口,compareTo()方法返回值为0

认为是重复元素

//Person类实现接口
//先按姓名比,再按年龄比
public int compareTo(Person o){
	int n1=this.getName().compareTo(o.getName());
    int n2=this.age-o.getAge();
    
    return n1==0?n2:n1;
}
comparator定制比较

比较器,实现定制比较

comparable::可比较的

//创建集合,并指定比较规则:先比较年龄再比较名字
TreeSet<Person> persons = new TreeSet<>(new Comparator(){
    public 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 s1=new Person("zhangsan",23);
Person s2=new Person("lisi",24);
Person s3=new Person("wangwu",22);
persons.add(s1);
persons.add(s2);
persons.add(s3);

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

TreeSet<String> treeSet=new TreeSet<>(new Comparator<String>(){
    //定制比较规则
    public int compare(String o1,String o2){
        int n1=o1.length()-o2.length();
        int n2=o1.compare(o2);
        return n1==0?n2:n1;
    }
});

//添加数据
treeSet.add("helloworld");
treeSet.add("lisi");
treeSet.add("beijing");
treeSet.add("code");

//打印数据

Map集合

特点:

  • 用于存储任意键值对
  • 键:无序、无下标、不允许重复(唯一)
  • 值:无序、无下标、允许重复

Map父接口使用

/*
存储的是键值对
键不能重复,值可以重复
无序
*/

//创建Map集合 Map是接口不能实例化
Map<String,String> map=new HashMap<>();

//添加元素
// "cn" 是键  “中国”是值
map.put("cn","zhongguo");
map.put("uk","yingguo");
map.put("usa","meiguo");

//打印元素个数
map.size();

//删除
//根据键删除
map.remove("usa");

//遍历
//keyset方法 返回的是一个集合
Set<String> keyset=map.keySet();
for(String key : keyset){
    System.out.println(key);
    map.get(key);//通过key 获得value
}
//使用 entrySet() 效率高与keySet()
//返回的是 entry类型的 set集合
Set<Map.Entry<String,String>> entries=map.entrySet();
for(Map.Entry<String,String> entry : entries){
    entry.getKey()  ;
    entry.getValue();
}
//判断
//值判断
map.containsValue("zhongguo");
//键判断
map.containsKey("cn");

Map集合的实现类

  • HashMap 【重点】

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

    • JDK1.0版本,线程安全,允许效率慢;不允许null作为key或是value
  • Properties

    • Hashtable的子类,要求key和value都是String。通常用于配置文件的读取
  • TreeMap

    • 实现了SortedMap接口(Map的子接口),可以对key自动排序

HashMap集合的使用

//默认初始容量 16 加载因子0.75

/*
存储结构:哈希表(数组+链表+红黑树)


*/
//先创建好学生类 Student 有姓名和学号
//集合
HashMap<Student,String> stu=new HashMap<Student,String>();

Student s1=new Student("zhangsan",100);
Student s2=new Student("lisi",101);
Student s3=new Student("wangwu",102);

stu.put(s1,"beijin");
stu.put(s2,"shanghai");
stu.put(s3,"hangzhou");
//键不能重复,新值会替代旧值
//个数
stu.size();

//虽然键相同,但是还是加进去了
//因为new了新对象
stu.put(new Student("liusi",101),"hangzhou");

//需要 重写 hashCode 和equals方法
//在Student类中 重写  
//就可以去重



//删除
stu.remove(s1);
//遍历
//keySet
for(Student key : stu.keySet()){
    key.toString(); //键
    stu.get(key);//值
}
//entrySet
for(Map.Entry<Student,String> entry : stu.entrySet()){
    entry.getKey();//键
    entry.getValue();//值
}
//判断
stu.containsKey();

总结:

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

TreeMap

TreeMap<Student,String> treeMap=new TreeMap<Student,String>();

Student s1=new Student("zhangsan",100);
Student s2=new Student("lisi",101);
Student s3=new Student("wangwu",102);
//添加元素
treeMap.put(s1,"beijin");
treeMap.put(s2,"shanghai");
treeMap.put(s3,"shenzen");
//会出异常 树的结构,需要定义比较规则
//在Studnet类中 实现接口 定义比较规则

public int compareTo(Student o){
    int n2=this.stuNo-o.getStuNo();
    return n2;
}
//添加不了,会替换,因为学号相同了,比较规则里比的是学号
treeMap.put(new Student("wangwu",102),"hangzhou");
//删除
treeMap.remove(s3);
//能删除,比的是学号
treeMap.remove(new Student("wangwu",102),"hangzhou");
//遍历
for(Student key : treeMap.keySet()){
key;
treeMap.get(key);
}

//
for(Map.Entry<Student,String> entry:treeMap.entrySet()){
    entry.getKey();
    entry.getValue();
}

//Panduan
treeMap.containsKey();

Colletions 工具类

  • 概念:集合工具类,定义了除存取以外的集合常用方法
List<Integer> list = new ArrayList<>();
list.add(12);
list.add(8);
list.add(20);
list.add(2);
list.add(18);
//sort 从小到大
Collections.sort(list);

//binarySearch 查找
int i = Collections.binarySeatch(12);
//负值说明没找到

//复制  报错了
List<Integer> dest=new ArrayList<>();
Collections.copy(dest,list);
//要先 把dest的长度扩展到和list的长度一致
for(int i=0;i<list.size();k++){
	dest.add(0);
}


//reverse 反转
Collections.reverse(list);

//shuffle 打乱
Collections.shuffle(list);

//补充:
// list 转成 数组

Integer[] arr=list.toArray(new Integer[0]);


//数组转成集合
String[] names={"zhangsan","lisi","wangwu"};
//这个集合是受限集合,不能添加和删除
List<String> list2=Arrays.asList(names);

//不要用基本类型int..去转集合 会有问题
Integer[] nums={100,200,300,400};
List<Integer>list3 =Arrays.asList(nums);

集合总结

  • 集合的概念

    • 对象的容器,和数组类似,定义了多个对象进行操作的常用方法
  • List集合:

    • 有序、有下标、元素可以重复(ArrayList,LinkedList,Vertor)
  • Set集合

    • 无序、无下标、元素不可重复(HashSet,TreeSet)
  • Map集合

    • 存储一对数据,无序、无下标,键不可重复,值可重复(HashMap,HashTable,TreeMap)
  • Collections:

    • 集合工具类,定义了除存取以外的集合常用方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值