Java的集合

集合

一些数据结构的统称集合 ,包含List,Set,Map

在这里插入图片描述

List(列表)

List就是列表,用来存储一组数据的数据结构

List可变长的数据结构,可以知道List里面存有多少个数据

List里面可以保存不同类型的数据

List是有序列表,数据可以重复

ArrayList

ArrayList是采用数组方式实现的

读取和遍历比较快,插入和删除数据的时候比较慢

  • List的基本使用

    add( )

    get( )

    size( )

//new一个ArrayList列表
List list = new ArrayList();//默认长度是10,自动扩展
list.add(5);
list.add("abc");
list.add(null);
list.add(5);

//size是返回列表的实际的个数
System.out.println(list.size());

//获取指定下标的数据
Object o = list.get(1);
System.out.println(o);

Integer m = (Integer) list.get(3);
System.out.println(m);

String n = (String)list.get(2);
System.out.println(n);

//for循环遍历list
System.out.println("=====遍历list========");
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

//foreach循环遍历list
System.out.println("====foreach==遍历list=====");
for(Object obj:list){
System.out.println(obj);
}
  • List的扩展
//list.add(x,x)括号里面两个数字,逗号隔开
 //在指定位置插入数据,插入的数据就在指定的下标,原来的数据往后移一位
 list.add(2,3.15);

 //list.set()替换指定下标位置的元素
 list.set(4,true);

 //删除指定下标的元素
 list.remove(3);

 //判断是否包含某个元素,如果包含返回true
 System.out.println("是否包含abc:" + list.contains("abc"));

 //返回指定元素在列表中的序号:没有找到返回-1
 System.out.println(list.indexOf("abc"));
 System.out.println(list.lastIndexOf("abc"));



 //截取子列表,左闭右开区间
 List listSub = list.subList(1,3);
 System.out.println(listSub);

 //清除列表所有数据
 list.clear();

 //List列表转数组
Object[]array =  list.toArray();
 System.out.println("数组长度:" + array.length);

 List list1 = Arrays.asList();
 System.out.println();


 //判断列表是否是空的(没有元素)是空返回true不是空返回false
 System.out.println(list.isEmpty());
LInkedList

采用双向链表实现的,插入和删除速度快,查询和遍历速度慢

在这里插入图片描述

  • 插入和删除速度快
  • 查找和遍历速度慢
  • 链里面的数据是保存的地址
  • 每一个节点除了自身数据的地址外,还保存上一个和下一个节点的地址

LinkedList的一些特殊的方法

public static void main(String[] args) {
    //创建一个LinkedList对象
    LinkedList list = new LinkedList();
    list.add(10);
    //在列表的最前面插入一个元素
    list.addFirst(5);
    //在列表的最后面插入一个元素
    list.addLast(9);

    System.out.println("=======遍历列表========");
    for(Object obj:list){
        System.out.println(obj);
    }

    //获取第一个元素
    System.out.println("第一个元素:" + list.getFirst());
    //获取最后一个元素
    System.out.println("最后一个元素:" + list.getLast());

    //删除第一个节点
    list.removeFirst();
    //删除最后一个节点
    list.removeLast();

    list.add(50);
    list.add(10);

    //出栈:弹出第一个元素(节点),会从列表中删除
    System.out.println("弹出元素:" + list.pop());
    //入栈(压栈):在最前面插入一个元素(节点)
    list.push(23);

    System.out.println("=======遍历列表========");
    for(Object obj:list){
        System.out.println(obj);
    }
}
泛型

因为List可以存各种类型的数据,但是取出来都是Objest,所以需要进行强制转换

泛型就是用来解决这个问题的,在创建List对象时指定存储的类型,在add和get自动就采用泛型指定的类型

定义方式:ListlistStr = new LinkedList<>();

泛型使用

//泛型
//定义泛型:定义变量的时候,类型后面跟上尖括号,尖括号写上那个数据类型
//new  对象的时候,类后面也要有尖括号,尖括号里不写类型,默认跟定义变量泛型一致
//泛型只能使用引用类型,不能使用基本类型
List<String>listStr = new LinkedList<>();
//一旦指定类型后,相关方法的参数,返回类型都跟泛型的类型一样
listStr.add("aaaaaaaaa");
listStr.add("bbbbbbbbb");
String s = listStr.get(0);
System.out.println(s);

Set

无序集合,元素不重复

没有索引(序号),不能通过下标访问

哈希表(hash table)

哈希表,散列表,是一种高效的数据结构

要保存的数据称为值,根据hash算法给每一个值算出hash code

保存数据用hash code 跟值一一对应

如下图所示,左边是数组方式保存数据,右边就是哈希表方式保存,中间是一个模拟的hash算法

在这里插入图片描述

hash table保存数据的原理

根据hash code从表里面找是否存在:

  • 不存在,直接添加
  • 存在,再去判断equals是否相等
    • false,直接添加
    • true,说明两个值一样,不添加

Hash code结论:

  • 两个值的hash code相同,它们的equals不一定相同
String str1="通话";
String str2="重地";
System.out.println(str1.hashCode());//1179395
System.out.println(str2.hashCode());//1179395
System.out.println(str1.equals(str2));//false
  • 两个值的equals相同,hash code不一定相同
//两个对象的equals相同,hash code不一定相同
    Student student1 = new Student(100,"张三");
    Student student2 = new Student(100,"李四");
    System.out.println(student1.hashCode() == student2.hashCode());


}

static class Student {
    private int num;
    private String Name;

    public Student(int num, String name) {
        this.num = num;
        Name = name;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return num == student.num && Name.equals(student.Name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(num, Name);
    }
}
  • 两个值的hash code 相同,equls也相同,这两个值一定相同

HashSet

采用hash表实现
元素不重复,无序的,允许存null

HashSet的常用方法:

public static void main(String[] args) {
    //创建HashSet,默认长度16,加载因子为0.75
    HashSet <String>set = new HashSet<String>();
    //往set添加元素
    set.add("Java");
    set.add("Html");
    set.add("SQL");
    set.add("Java");//内容重复,在set里里面只有一个

    //返回set的长度
    System.out.println(set.size());

    //读取set的元素:遍历
    for (String str:set) {
        System.out.println(str);
    }

    //查找是否包含某个对象(对象类要重写hash code 和 equals)
    System.out.println(set.contains("SQL"));

    //删除set里面的元素
    set.remove("Java");

    //清空set
    set.clear();

    //判断set是否是空的
    System.out.println(set.isEmpty());


}

练习

给出一个数组,把数组中重复的元素去掉

{1,30,25,40,18,30,22,40}

//数组去除重复数据
int[] arr1 = {1,30,25,40,18,30,22,40};
HashSet <Integer>  set1 = new HashSet<Integer>();
for (int a:arr1) {
    set1.add(a);
}
int[] arr2 = new int[set1.size()];
int i = 0;
for (int a:set1) {
    arr2[i] = a;
    i++;
}
System.out.println(Arrays.toString(arr2));

二叉树

  • 满二叉树

  • 完全二叉树

    最底层的分支可以不是完全的,但是必须要先保证左边的分支全部填满

在这里插入图片描述

  • 二叉查找树

在这里插入图片描述

  • 平衡二叉树

    左右子树的高度差小于等于1,并且左右子树分别都是平衡的二叉树

在这里插入图片描述

  • 红黑树

    它是一种自平衡的二叉查找树

    特征:

    1. 节点只有红色和黑色

    2. 根节点是黑色

    3. 叶子节点是黑色,叶子节点村NIL

    4. 一个节点为红色,则他的两个子节点必须为黑色(从根节点到叶子节点的所有路径不可能存在两个连续的红色节点)

    5. 每一个节点到叶子节点的所有路径都包含相同数目的黑色节点

      在这里插入图片描述

TreeSet

TreeSet的特性

  • TreeSet采用红黑树数据结构实现

  • 不能添加null

  • 不能添加重复数据

  • 添加的元素会被排序,遍历出来的是按顺序排列的

  • TreeSet的元素必须要实现Comparable接口(如果没有实现Compareable接口,运行时抛出类型转换异常)

常用的方法

public static void main(String[] args) {

    //创建set 
    TreeSet<Integer> set = new TreeSet<>();
    set.add(20);
    set.add(25);
    set.add(8);
    set.add(16);
    set.add(10);

    //返回元素的个数
    System.out.println("元素的个数:" + set.size());

    //返回排序后的第一个元素
    System.out.println("first:" + set.first());

    //返回排序后的最后一个元素
    System.out.println("last:" + set.last());

    //返回比指定元素大的最小元素    ceiling:天花板
    System.out.println("ceiling:" + set.ceiling(18));

    //返回比指定元素小的最大元素    floor:地板
    System.out.println("" + set.floor(18));
    
    //遍历是按元素排序显示
    for (Integer i:set) {
        System.out.println(i + " ");
    }

    //删除指定的对象
    set.remove(20);

    //清空所有的元素
    set.clear();

    //判断是否是空
    System.out.println("判断是否是空:" + set.isEmpty());//true

TreeSet存放自定义的类型

  • 定义Egg类

    必须实现接口Compareable

    实现CompareableTo()方法,当前对象比参数大返回1,小于返回-1,等于返回0

///类要放进TreeSet(排序),必须要实现Comparable接口,泛型和这个类一样
public class Egg implements Comparable<Egg> {
    private float weight;

    public Egg(float weight) {
        this.weight = weight;
    }

    public Egg() {
    }

    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) {
        this.weight = weight;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Egg egg = (Egg) o;
        return Float.compare(egg.weight, weight) == 0;
    }

    @Override
    public int hashCode() {
        return Objects.hash(weight);
    }

    @Override
    public String toString() {
        return "Egg{" +
                "weight=" + weight +
                '}';
    }

    /**
     * 实现compareTo方法
     *  o 跟它比较的另一个对象
     *   1   当前对象大于参数对象,返回  1    (升序排列,如果要降序就返回 -1)
     *  -1   当前对象小于参数对象,返回 -1
     *   0  当前对象跟参数对象相等,返回  0
     */

    @Override
    public int compareTo(Egg o) {
        if(this.weight > o.weight){
            return 1;
        }else if(this.weight < o.weight){
            return -1;
        }else{
            return 0;
        }
    }
}
  • 测试代码

    TreeSet里面的对象按升序排列

//   TreeSet存放自定义对象
TreeSet<Egg> eggs = new TreeSet<>();
eggs.add(new Egg(50.0f));
eggs.add(new Egg(45.5f));
eggs.add(new Egg(78.5f));
eggs.add(new Egg(41f));

for (Egg egg:eggs) {
    System.out.println(egg);
}

练习

创建运动员(SportsMan)对象,有个成绩(score)和姓名(name)属性

按照的得分从高到底进行排序,打印运动员的姓名和成绩

  • SportsMan类

    public class SportsMan implements Comparable<SportsMan>{
       private String name;
       private int score;
    
        public SportsMan(String name, int score) {
            this.name = name;
            this.score = score;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getScore() {
            return  score;
        }
    
        public void setScore(int score) {
            this.score = score;
        }
    
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            SportsMan sportsMan = (SportsMan) o;
            return score == sportsMan.score && Objects.equals(name, sportsMan.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name, score);
        }
    
        @Override
        public String toString() {
            return "SportsMan{" +
                    "姓名:'" + name + '\'' +
                    ", 成绩:" + score +
                    '}';
        }
    
    
        @Override
        public int compareTo(SportsMan o) {
            if(this.score > o.score){
                return -1;//升序
            }else if(this.score < o.score ){
                return 1;//降序
            }else{
                return 1;
            }
        }
    }
    
  • 测试类 SportsTest

    public class SportsTest {
        public static void main(String[] args) {
    
    
            TreeSet<SportsMan> sportsman = new TreeSet<>();
            sportsman.add(new SportsMan("张三",60));
            sportsman.add(new SportsMan("李四",85));
            sportsman.add(new SportsMan("王五",78));
            sportsman.add(new SportsMan("赵六",90));
            sportsman.add(new SportsMan("刘七",
    
            for (SportsMan s: sportsman) {
                System.out.println(s);
            }
    
        }
    }
    

Map

  • 保存键值对数据(key - value)

    如 :yyds -> 永远的神

    ​ emo -> 抑郁了

  • key不能重复,value可以重复

  • key和value都可以为null

HashMap

采用数组 + 链表 + 红黑树 的数据结构来实现的

先根据hash code 保存数组中

如果出现hash碰撞,用链表

链表长度超过8,改用红黑树

在这里插入图片描述

基本方法的使用

public static void main(String[] args) {
    //默认长度是16,加载因子0.75
    HashMap<String,String> map = new HashMap<>();
    //往map插入数据,第一个参数是key,第二个参数是value
    map.put("yyds","永远的神");
    map.put("emo","抑郁了");
    map.put("u1s1","有一说一");
    //根据key查询对象value
    System.out.println(map.get("yyds"));

    //判断map中是否存在某个key
    System.out.println("是否存在key:" + map.containsKey("yyds"));
    //判断map中是否存在某个value
    System.out.println("是否存在value:" + map.containsValue("有一说一"));

    //返回map元素长度
    System.out.println(map.size());

    //遍历map
    System.out.println("==========遍历value==========");
    Collection<String> values = map.values();
    for (String str: values) {
        System.out.println(str);
    }

    System.out.println("==========遍历key==========");
    Collection<String> key = map.keySet();//以set数据类型返回所有的key
    for (String str: key) {
        System.out.println(str);
    }

    //同时遍历key和value
    System.out.println("=======遍历entry=========");
    Set<Map.Entry<String, String>> entries = map.entrySet();//Map.Entry:内部的接口或者类
    for (Map.Entry<String,String> entry:entries) {
        System.out.println(entry.getKey() + "," + entry.getValue());
    }

    //删除key为指定的元素
    map.remove("yyds");

    //清除所有元素
    map.clear();

    //判断map是否为空
    System.out.println(map.isEmpty());
}

迭代

map不能做迭代遍历

list做迭代遍历

List<Integer> list = new ArrayList<>();
list.add(9);
list.add(6);
list.add(3);
list.add(45);
list.add(42);
list.add(13);

//返回迭代器,迭代器里面存着数据
Iterator<Integer> iterator = list.iterator();
//hasNext()方法判断里面还有没有数据
while (iterator.hasNext()){
    //next()从迭代器中取出数据,取一个少一个
    Integer integer = iterator.next();
    System.out.println(integer);
}

set做迭代遍历

/*set做迭代遍历 */
Set<Integer> set = new HashSet<>();
set.add(52);
set.add(32);
set.add(20);
set.add(12);
set.add(5);
set.add(45);

Iterator<Integer> iterator1 = set.iterator();
while(iterator1.hasNext()){
    Integer integer= iterator1.next();
    System.out.println(integer);
}

Collections集合工具类

  • 面试题:Collection跟Collections的区别

    Collection:是一个接口,它是List和Set的父接口

    Collections:是一个处理集合类型数据的工具类

  • Collection 的常用方法

List<Integer> list = new ArrayList<>();
list.add(56);
list.add(50);
list.add(20);
list.add(30);
list.add(10);

//随机打乱list的顺序
Collections.shuffle(list);
for (Integer i: list) {
    System.out.print(i + " ");
}

//让list逆序排列
System.out.println("=====逆序排列=====");
Collections.reverse(list);
for (Integer i: list) {
    System.out.print(i + " ");
}

//让list排序
//如果要排序,list里面的类型必须要实现Comparable接口(类似TreeSet里面的对象)
Collections.sort(list);
System.out.println("========排序========");
for (Integer i :list){
    System.out.print(i + " ");
}

//交换指定位置的元素
Collections.swap(list,1,3);
System.out.println("====交换=====");
for (Integer i:list) {
    System.out.print(i + " ");
}

//返回集合中的一个元素
System.out.println("====最大====");
Integer max = Collections.max(list);
System.out.println(max);

System.out.println("======最小=====");
Integer min = Collections.min(list);
System.out.println(min);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值