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());
        }
    }

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

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java中Scanner用法总结

    Java中Scanner用法总结最近在做OJ类问题的时候,经常由于Scanner的使用造成一些细节问题导致程序不通过(最惨的就是网易笔试,由于sc死循环了也没发现,导致AC代码也不能通过。。。),因此对Scanner进行了一些总结整理。Scanner类简介Java5添加了java.util.Scanner类,这是一个用于扫描输入文本的新的实用程序。它是以前的StringTokenizer和Matcher类之间的某种结合。由于任何

    2022年7月20日
  • navicate 15.0.25 激活码【2021.7最新】[通俗易懂]

    (navicate 15.0.25 激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~ML…

    2022年3月21日
  • .net AutoEventWireup介绍

    .net AutoEventWireup介绍ASP.NET页会引发诸如Init、Load、PreRender等生命周期事件。默认情况下,可以使用Page_事件名称的命名约定将页事件绑定到方法。例如,若要为页的Load事件创建处理程序,可以创建名为P…

    2022年5月28日
  • 如何修改opkg 源

    如何修改opkg 源http://downloads.openwrt.org.cn/上面的链接是openwrt国内的源,但是只有适合以下几个系统的源Hacked/18-Jun-201413:58-OpenWrt-DreamBox/01-J

    2022年5月9日
  • python 之字符编码

    一了解字符编码的储备知识python解释器和文件本编辑的异同相同点:python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样不同点:文本编辑器

    2022年3月29日
  • leetcode-33搜索旋转排序数组(二分)[通俗易懂]

    leetcode-33搜索旋转排序数组(二分)[通俗易懂]整数数组 nums 按升序排列,数组中的值 互不相同 。在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。给你 旋转后 的数组 nums 和一个整数 ta

    2022年8月8日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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