Java集合分类以及各自特点

Java集合分类以及各自特点Java分类以及各自的特点,对集合中的自定义类元素排序,比较器集合分为Map和Collection两大类常用的就是ArrayList,LinkedList,HashSet,LinkedHashSet,TreeSet,HashMap,LinkedHashMap,TreeMap;

大家好,又见面了,我是你们的朋友全栈君。

  1. Java分类
    集合分为Map和Collection两大类
    集合体系图

常用的就是ArrayList,LinkedList,HashSet,LinkedHashSet,TreeSet,HashMap,LinkedHashMap,TreeMap;
数组和集合的区别
区别1:
数组可以存储基本数据类型/引用数据类型
基本数据类型存的是值 引用数据类型存的是地址
数组在创建的时候 就会定义存储的数据类型 也就是只能存储一种数据类型
集合只能存储引用数据类型(对象)
集合中也可以存储基本数据类型(装箱)最终存储的还是 Object
如果没有泛型限定 默认存储的都是 Object类型的数据 也就是任意类型
区别2
数组长度是固定的,不能自动增长
集合是长度可变的,根据元素的多少来决定长度

集合中保存的都是引用类型,如果是基本数据类型的话会自动转成其包装类.

List是有序的(存取顺序),可以装重复元素,有索引
Set是无序的(存取顺序),不能重复,无索引值.

  1. List下面的三个子集合的区别 |–Vector 底层数据结构是数组 查询快 增删慢 线程安全 效率低 默认长度是10 超过就会100%延长 变成20 浪费空间 |–ArrayList 底层数据结构是数组 查询快 增删慢 线程不安全 效率高
    默认长度是10 超过就会new一个新的数组 50%延长 节省空间 |–LinkedList 底层数据结构是链表(双向链表)
    查询慢 增删快 线程不安全 效率高

  2. Set集合的子集合 HashSet 按照哈希算法来存取集合中的对象 存取速度比较快

    当程序向HashSet中 add()的一个对象的时候, 先用hashCode方法计算出该对象的哈希码 哈希码不一致 添加 哈希码一致
    不添加 相同对象不添加 然后用equals判断对象的属性是否一致 比较结果为false就添加 true就不添加 不同对象添加

    基本数据类型包装类/String 已经重写了hashCode 和 equals 会自动比较
    自定义实现类要重写其hashCode和equals方法,规定自定义类的比较规则来排重.

    LinkedHashSet 特点:
    1.有序(存取一致)
    是Set集合中唯一一个能保证怎么存就怎么取的集合对象
    2.排重
    3.底层是双向链表 HashSet的方法怎么用 LinkedHashSet就怎么用 TreeSet 二叉树 实现了SortedSet接口 能够对集合中对象进行排序

    特点:
    1.排序的(升序) 自然排序 根据ASCII表大小排序
    2.排重
    3.无序(存取不一致)
    4.底层是一个二叉树(左序中序右序)
    5.只能存储同一种类型 才能排序 不然就会出现转换异常 自定义实现类 如何比较

方式一 实现 Comparable 接口 重写 comparaTo方法 这种方式也称为元素的自然排序 或者是默认顺序排序 int
compareTo(T o) 比较此对象与指定对象的顺序。 如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
负整数 此对象 < 指定对象 0 此对象 == 指定对象 正整数 此对象 > 指定对象

方式二 Comparator比较器

    TreeSet(Comparator<? super E> comparator) 
    接口 Comparator<T>
        int compare(T o1, T o2) 
        比较用来排序的两个参数。
        根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。

    在实际工作中 尽量不要修改源码 使用Comparator比较器 比较个性的东西
区别:
    TreeSet构造函数未传入比较器,默认按照类中的Comparable比较 如果不写 就报错
    TreeSet传入Comparator比较器 就优先按照Comparator比较

遍历集合的时候 List: 普通for循环 使用get()获取元素 调用 iterator() hasNext()
next()获取元素 增强for循环 只要可以使用Iterator 的类都可以使用
Vector 集合用的是 Enumeration Set: 调用 iterator() 增强 for

普通for循环 迭代器 增强for循环 是否可以在遍历的过程中删除元素?

普通 for 可以 迭代器 自己的remove() 可以 增强 for 不可以

当在用迭代器对集合进行遍历的是候,用集合的方法对集合进行操作(remove或者add)的时候,
就存在安全隐患,并发异常.可以使用ListIterator的remove方法进行删除.

  1. Map集合 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

    Map接口和Collection接口的不同
    1.Map是双列的(夫妻 有结婚证这个联系)
    Collection是单列的(单身狗)
    2.Map的键是唯一的
    Collection的子体系 Set是唯一的
    3.Map集合的数据结构是针对键有效的 跟值无关
    Collection集合的数据结构是针对元素有效 特点:
    1.根据键来排重 也就是相同键的元素存储在同一个Map集合中 后添加的键值元素会将之前存储的相同的键值元素替代
    2.键和值 都需要是引用数据类型

    实现类:
    1.HashTable 底层是哈希表 不可以存入null键null值 线程同步的 jdk1.0 效率低
    2.HashMap 底层是哈希表 可以存入null键null值 线程不同步的 jdk1.2 效率高
    3.TreeMap 底层是二叉树 线程不同步的 可以用于给Map集合中的键进行排序 和Set很像 其实 Set底层就是用了Map集合

//遍历map集合,
        //方法一: Set<K> keySet() 返回此地图中包含的键的Set视图。  
        Set<String> set = map.keySet();
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            String value = map.get(key);
            System.out.println(key+".."+value);
        }

        //增强for
        for(String se:map.keySet()) {
            System.out.println(se+"="+map.get(se));
        }

        //方法二 Set<Map.Entry<K,V>> entrySet() 返回此地图中包含的映射的Set视图。  
        Set<Map.Entry<String, String>> entry = map.entrySet();
        Iterator<Map.Entry<String, String>> it2 = entry.iterator();
        while(it2.hasNext()) {
            Map.Entry<String, String> en = it2.next();
            String key = en.getKey();
            String value = en.getValue();
            System.out.println(key+"----"+value);
        }

        //增强for   Set<Map.Entry<K,V>> entrySet()
        for(Map.Entry<String, String> en:map.entrySet()) {

            System.out.println(en.getKey()+"------"+en.getValue());
        }

HashSet,LinkedHashSet,HashMap,LinkedHashMap,
这四个集合如果不是自定义类会自动去重,因为其他的类都自己重写了equals方法和hashCode方法,自定义类的话就需要我们自己在自定义类中重写这两个方法.
例如:

    public class Girl { 
   
    private String name;
    private int age;
    private String phone;

    @Override
    public String toString() {
        return "Girl [name=" + name + ", age=" + age + ", phone=" + phone + "]";
    }
    public int hashCode() {
        return name.hashCode() + this.age*33;
    }

    public boolean equals(Object obj) {
        if(!(obj instanceof Girl)) {
            return false;
        }
        Girl girl = (Girl)obj;
        return this.name.equals(girl.name)&&this.age==girl.age;
    }
}

TreeSet,TreeMap保存非自定义类会自动根据Ascll码(升序)排序,如果是是自定义类就需要自己写比较器.
两种比较器Comparator和Comparable,
实际情况下用Comparator,用法:

1.直接写成匿名内部类
    TreeSet tree = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Computer c1 = (Computer)o1;
                Computer c2 = (Computer)o2;
                if(c1.getType().length()>c2.getType().length()) {
                    return 1;
                }else if(c1.getType().length()==c2.getType().length()) {
                    if(c1.getType().equals(c2.getType())) {
                        return (int) (c1.getSum()-c2.getSum());
                    }
                    return c1.getType().compareTo(c2.getType());
                }
                return -1;
    }});
2.写一个类实现Comparator接口,并重写compare方法
package com.qf.test;
import java.util.Comparator;
public class Sort1 implements Comparator{ 
   
    @Override
    public int compare(Object o1, Object o2) {
        Computer c1 = (Computer)o1;
        Computer c2 = (Computer)o2;
        if(c1.getType().length()>c2.getType().length()) {
            return 1;
        }else if(c1.getType().length()==c2.getType().length()) {
            if(c1.getType().equals(c2.getType())) {
                return (int) (c1.getSum()-c2.getSum());
            }
            return c1.getType().compareTo(c2.getType());
        }
        return -1;
    }

}


TreeSet tree = new TreeSet(new Sort1());

Comparable的用法

public class Person implements Comparable{ 
   
    private String name;
    private int 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;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public Person() {
        super();
    }
    @Override
        public int compareTo(Object o) {
            Person person = (Person) o;
            /*if(this.getAge() > person.getAge()) { return 1; } if(this.getAge() == person.getAge()) { return this.getName().compareTo(person.getName()); } return -1;*/
            /*int num = this.getAge() - person.getAge(); return num==0?this.getName().compareTo(person.getName()):num;*/

            /*if(this.getName().length()>person.getName().length()) { return 1; } if(this.getName().length()==person.getName().length()) { if(this.getName().equals(person.getName())){ return this.getAge()-person.getAge(); } return this.getAge()-person.getAge(); } return -1;*/
            int length = this.name.length()-person.name.length();
            int num = length ==0?this.name.compareTo(person.name):length;
            return num==0?this.age-person.age:num;
    }
}

最后讲一下 在ArrayList,LinkedList,HashSet,LinkedHashSet,HashMap,LinkedHashMap,这6种集合中元素要排序都要自己写,这里就演示一下,ArrayList中保存的是自定义类的时候的排序.

//定义Comparator比较器
import java.util.Comparator;
//排序规则:先按电脑的型号排序,型号相同按内存排(如果有固态硬盘,要加上固态硬盘内存的大小)
public class Sort1 implements Comparator{ 
   

    @Override
    public int compare(Object o1, Object o2) {
        Computer c1 = (Computer)o1;
        Computer c2 = (Computer)o2;
        if(c1.getType().length()>c2.getType().length()) {
            return 1;
        }else if(c1.getType().length()==c2.getType().length()) {
            if(c1.getType().equals(c2.getType())) {
                return (int) (c1.getSum()-c2.getSum());
            }
            return c1.getType().compareTo(c2.getType());
        }
        return -1;
    }

}

//自定义Computer类
package com.qf.test;
public class Computer{ 
   
    private String type;
    private double neicun;
    private double gutai;

    private double sum;
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public double getNeicun() {
        return neicun;
    }
    public void setNeicun(double neicun) {
        this.neicun = neicun;
    }
    public double getSum() {
        return sum;
    }
    public Computer(String type, double neicun,double gutai) {
        super();
        this.type = type;
        this.neicun = neicun;
        this.gutai = gutai;
        this.sum =neicun+gutai;
    }
    @Override
    public String toString() {
        return "Computer [type=" + type + ", neicun=" + neicun + "]";
    }
}

//排序类
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class Sort { 
   
    public static void main(String[] args) {
        demo2();
    }
    public static void demo2() {
        Sort1 sor  = new Sort1();//实例化实现了Comparator比较器的类
        ArrayList list = new ArrayList();
        list.add(new Computer("huasuo",555,452));
        list.add(new Computer("hu",456,74));
        list.add(new Computer("hua",524,785));
        list.add(new Computer("huas",852,258));
        list.add(new Computer("huasuo",963,456));
        //这几个集合不会自动比较,所以需要用到基本的排序方法(冒泡,选择,快速)进行排序,只是在比较的时候调用自己重写的compare方法来比较,这样的话比较的规则就是你定义的规则.
        for(int i=0;i<list.size();i++) {
            for(int j=0;j<list.size()-1;j++) {
            //调用compare方法比较,满足条件就交换j与j+1位置上面的值进行交换,用集合的方法交换
                if(sor.compare(list.get(j), list.get(j+1))>0) {
                    Computer c = (Computer) list.get(j);
                    list.set(j, list.get(j+1));
                    list.set(j+1, c);
                }
            }
        }
        Iterator it = list.iterator();
        while(it.hasNext()) {
            Computer com = (Computer) it.next();
            System.out.println(com.getType()+"----"+com.getSum());
        }
    }

}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140568.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Windows注入与拦截(1) — DLL注入的基本原理「建议收藏」

    Windows注入与拦截(1) — DLL注入的基本原理「建议收藏」一.DLL注入技术的用途从前面的《Windows内存体系》系列文章中我们可以知道,在Windows系统中,每个进程都有自己私有的地址空间。当我们用指针来引用内存的时候,指针的值表示的是进程自己的地址空间的一个虚拟的内存地址。进程不能通过指针来引用其他进程地址空间的内存。因此,如果一个进程有缺陷会导致其引用和覆盖随机地址处的内存,那么这个缺陷的影响就会不会扩散到其他的进程。独立的地址空间有…

  • 提交缺陷报告

    提交缺陷报告一、软件缺陷的判定1.什么是缺陷软件存在着不符合质量需求或违背软件用户、客户、企业意愿的问题,这就是软件缺陷(Defect),又叫“Bug(臭虫)”。2.软件缺陷的判定准则软件未达到产品说明书标明的功能;产品说明书简称为说明(spec)或产品说明(productspec),是软件开发小组的一个协定。它对开发的产品进行定义,给出产品的细节、如何做、做什么、不能做什么。这种协定从简单的口头说明到正式的书面文档有多种形式。软件出现了产品说明书指明不会出现的错误;如金融软件

  • phpstorm-2021.5.1激活码【在线注册码/序列号/破解码】「建议收藏」

    phpstorm-2021.5.1激活码【在线注册码/序列号/破解码】,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • Div+CSS – 简单布局

    Div+CSS – 简单布局Div+CSS – 简单布局

  • Centos7磁盘阵列部署与修复「建议收藏」

    Centos7磁盘阵列部署与修复「建议收藏」Centos7磁盘阵列部署与修复一、部署RAID10#1、虚拟机添加4块20G的硬盘设备#2、mdadm命令,其中-n4代表使用4块磁盘,-l10代表使用RAID10技术mdadm-Cv/dev/md0-ayes-n4-l10/dev/sdb/dev/sdc/dev/sdd/dev/sde#3、制作好的RAID磁盘阵列格式化为ext4mkfs.ext4/dev/md0#4、创建挂载点,进行磁盘设备挂载mkdir/RAIDmount/dev/md0/RA

  • poj3617Best Cow Line

    poj3617Best Cow Line

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号