Java容器基础

Java容器基础

Map

Map自成一体,其根接口不是Collection。Map接口有两个子类HashMap和TreeMap。HashMap有一个子类LinkedHashMap.

各个容器之间继承(接口实现)关系简要介绍

  • Collection是Set、List、Queue的根接口。
  • Map自成一体,Collection不是其父接口。
  • Iterator是迭代器,用于遍历集合。
  • Comparator是比较器,用于TreeSet中的排序。

Collection常用方法

boolean add(E e)
boolean addAll(Collection c)

boolean remove(E e)
boolean removeAll(Collection c)
void clear()

判断集合中是否存在元素

boolean contains(E e)
boolean containsAll(Collection c)

判空

  • boolean isEmpty() :判断集合是否为空,如果为空返回true;否则返回false

迭代器

Iterator iterator()
iterator.hasNext()
iterator.next()
iterator.remove()
iterator.forEachRemaining(lambda表达式)

交集

  • boolean retainAll(Collection c) :将集合与c中元素的交集存入集合中,原集合中的元素会被删除

长度

  • int size() :获取集合的元素个数

转化成数组

  • Object[] toArray() :把集合转化成数组

Collections

介绍

Collections是集合中的一个工具类,它里面提供了一系列静态方法用来操作集合元素。

Collections工具类中适用于List的静态方法

  1. 复制
  • Collections.copy(List dest,List src) :把src集合中的元素复制到dest中
  • 注意点
    • 如果src的长度大于dest的长度,那么会抛异常,复制失败。
    • 如果src的长度等于dest的长度,那么dest中的元素会被全部替换掉。
    • 如果src的长度(m)小于dest的长度(n),那么dest中的前m个元素会被src的元素替换掉,后面剩余的元素不变。
  1. 替换
  • Collections.fill(List<T> list,T obj ) :用obj将list中的所有元素都替换掉
  1. 随即调整
Collections.shuffle(List<T> list)
Collections.shuffle(List<T> list,Random random)
  1. 排序
  • Collections.sort(List<T> list) :根据元素的自然顺序来对集合中的元素进行递增排序
  1. 查找
Collections.min(List<T> list)
Collections.max(List<T> list)
Collections.binarySearch(List<T> list,T obj)

Set

Set特点

元素无序且不可重复。(无序是指元素存入的顺序和元素取出的顺序是不一致的)

HashSet

HashSet存储元素时,是根据该元素的哈希码进一步计算出该元素在容器中的存储位置。而Set中不允许有重复元素,故当obj1.equals(obj2)为true时,就必须保证obj1和obj2的hashCode()是一样的。所以,自定义的类要存储到HashSet中,就必须重写equals()和hashCode()方法(两个方法必须都重写)。

TreeSet

简要介绍

TreeSet是SortedTree的实现类,所以TreeSet里面的元素需要排序。排序有两种方式:自然排序和指定排序。

自然排序

实现方式

在自定义的类对象中去继承Comparable接口,并实现compareTo(Object obj)方法;该方法比较自定义类与obj的大小,若前者大,则返回一个大于0的整数;若两者相等,则返回0;若后者大,则返回一个小于0的整数。

public class Person implements Comparable {
    private String name;
    private int age;

    public Person() {

    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }


    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }


    @Override
    //重写equals方法
    public boolean equals(Object obj) {
        Person p = null;
        if (obj instanceof Person) {
            p = (Person) obj; //强转
            if ((p.name.equals(this.name)) && (p.age == this.age))
                return true;
        }
        return false;
    }


    @Override
    // 重写hashCode方法
    public int hashCode() {
        int code;
        code = (this.name == null ? 0 : this.name.hashCode());
        code = 10 * this.age + code;
        return code;
    }

    // 实现compareTo方法
    @Override
    public int compareTo(Object obj) {
        // 自定义比较规则:按名字拼音排序,如果名字相同,则按年龄排序(递增排序)
        Person p = null;
        if (obj instanceof Person)
            p = (Person) obj; //强转
        Comparator comparator = Collator.getInstance(Locale.CHINA); //获取按照名字拼音排序的比较器
        int result = comparator.compare(this.name, p.name);
        if (result == 0) //名字相同
            return this.age > p.age ? 1 : (this.age == p.age ? 0 : -1);
        else
            return result;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '/'' +
                ", age=" + age +
                '}';
    }
}
复制代码

注意:比较大小的规则是自己定义的。

指定排序

实现方式

  • 01.自定义一个比较器(即自定义一个类),让该类继承Comparator接口,并实现compare(T t1,T t2)方法。该方法比较自定义类与obj的大小,若前者大,则返回一个大于0的整数;若两者相等,则返回0;若后者大,则返回一个小于0的整数。
  • 02.在创建TreeSet时,要么所使用的泛型的类已经实现了Comparable接口,要么把该比较器的实例传入TreeSet的构造方法中。否则,会报错。因为创建TreeSet时,必须有排序方式(自然排序/指定排序二选一)。
public class MyComparator implements Comparator<Student> {
    @Override
    //实现compare方法
    public int compare(Student p1, Student p2) {
        Comparator comparator = Collator.getInstance(Locale.CHINA);
        int result = comparator.compare(p1.getName(), p2.getName()); //按照中文拼音顺序来比较名字
        if (result == 0) {  //名字相同
            return p1.getAge() > p2.getAge() ? 1 : (p1.getAge() == p2.getAge() ? 0 : -1);
        }
        return result;
    }
}
复制代码

测试代码:

@Test
    public void test3() {
        // 使用TreeSet时,要么所使用的泛型的类已经实现了Comparable接口;
        // 要么自定义一个比较器来继承Comparator接口,然后把自定义的构造器传入new TreeSet(new MyComparator())中
        TreeSet<Student> treeSet = new TreeSet<>(new MyComparator());
        treeSet.add(new Student("包宝宝", 20));
        treeSet.add(new Student("包宝宝", 19));
        treeSet.add(new Student("卞哈哈", 25));
        treeSet.add(new Student("陈浩hao", 30));
        treeSet.add(new Student("陈浩hao", 12));
        treeSet.add(new Student("陈敏敏", 23));
        treeSet.add(new Student("储玉玉", 34));
        treeSet.add(new Student("许啊啊", 23));
        Iterator iterator = treeSet.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
复制代码

**注意:**在继承Comparator接口时,一定要加泛型,这样在实现compare方法时,才好比较两者大小。

List

List特点

List中的元素可以重复。

ArrayList

特点

  • 顺序表,是长度可变的数组
  • 允许对元素随机访问,访问速度快
  • 插入、删除元素的速度慢
  • ArrayList是线程安全的,若要获取线程安全的ArrayList,则:List list=Collections.synchronizedList(new ArrayList())

ArrayList常用方法

**注意:**此处介绍的方法是ArrayList特有的,Collection接口中的“普遍”方法就不介绍了。

T get(int index)
int indexOf(T e)
List<T> subList(int startIndex,int endIndex)

LinkedList

特点

  • LinkedList在内部采用双向循环链表实现
  • 插入、删除元素速度快
  • 访问元素速度慢

LinkedList常用方法

  • 获取表头元素
    T getFirst()
    T element()
    T peek()
    
  • 删除表头元素
    T removeFirst()
    boolean remove()
    T poll()
    
  • 在表尾添加元素
    void addLast()
    void add()
    boolean offer()
    

LinkedList特有方法

  • addFirst()
    addLast()
    
  • removeFirst()
    removeLast()
    
  • 获取
    getFirst()
    getLast()
    

Queue

略。

Map

HashMap

简介

与HashSet一样,HashMap也是基于哈希表来存储元素的,故,在使用HashMap 存储自定义对象时,必须重写equals()和hashCode()方法。

特点

  • 无序
  • 线程不安全

HashMap常用方法

V get(key)
V put(key,value)
boolean isEmpty()
boolean containsKey(K key)
boolean containsValue(V value)
V remove(K key)
Set<K> keySet()
Collection<V> values()
Set<Map.Entry<K,V>> entrySet()
int size()
map.forEach(lambda表达式)

HashMap的遍历方法

  • 直接获取所有的value,然后遍历
for(String value:map.values()){
           System.out.println(value); //该遍历方法的缺点就是不能获取key
       }
复制代码
  • 获取所有的键,然后根据键来获取值
Set<String> keySet = map.keySet(); //获取所有的key
        for(String key:keySet){
            System.out.println(key+":"+map.get(key));
        }
复制代码
  • 获取所有的键和值,遍历,然后分别获取键和值
for(Map.Entry<String,String> e:map.entrySet()){
            System.out.println(e.getKey()+":"+e.getValue());
        }
复制代码
  • 使用迭代器来遍历
// 获取迭代器
        Iterator it=map.entrySet().iterator();
        while(it.hasNext()){
            // 同时获取key和value
            Map.Entry<String,String> entry= (Map.Entry<String, String>) it.next(); //强转
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
复制代码
  • 使用Java8为Map新增的forEach方法来遍历
map.forEach((key,value)-> System.out.println(key+":"+value));
复制代码

原文 

https://juejin.im/post/5e78a7f06fb9a07c92055657

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java容器基础

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址