欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java集合分类以及各自特点

程序员文章站 2022-05-23 16:21:23
...
  1. Java分类
    集合分为Map和Collection两大类
    Java集合分类以及各自特点

常用的就是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());
        }
    }

}