JavaSE.08.集合

该博客聚焦JavaSE中的集合知识,介绍了Collection的线性列表储存方式及其中方法、迭代器和for - each,还阐述了Collection的实现类List、Set,以及Map的不同类型如HashMap、TreeMap等,另外提及了Collections和Properties。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaSE.08.集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYB9nosH-1604323457521)(/image-20201102153558400.png)]
在这里插入图片描述

1.Collection

Collection采用线性列表的储存方式,单列数据

1.集合,数组都是对多个数据进行存储操作的结构,简称Java容器
说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg...)
2.1数组在存储多个数据方面的特点
     数组初始化以后长度就确定了
     数组声明的类型,就决定了进行元素初始化的类型
2.2数组在存储多个数据方面的弊端
     一旦初始化以后,其长度不可修改
     数组中提供的方法非常有限,对于添加,删除,插入数据等操作,不方便
     获取数组中实际元素的个数,数组没有现成的方法,属性可用
     数组存储数据的特点:有序,可重复,对于无序或者不能重复的需求,无法做到
1.Collection中的方法
add(Object e)
addAll()
clear()清空集合元素
isEmpty()判断集合是否为空
contains(Object obj):判断集合中是否包含obj
containsAll(Collection col4):判断形参col4中的所有元素是否都存在于当前集合中
remove(Object obj):移出obj元素
removeAll(Collection col1):从当前集合中移出col1中的所有元素
col1.retainAll(Collection col2):取交集,并返回给当前集合
equals(Object obj):比较当前对象和形参对象中的元素是否全部相等
hashCode():返回当前对象的哈希值
toArray()集合转换为数组
Arrays.asList(objects)数组转换为集合
iterator():返回Iterator接口的实例,用于遍历集合元素
public class CollectionTest {
    @Test
    public void test1(){
        Collection col1 = new ArrayList();
        //add(Object e)
        col1.add("aa");
        col1.add(123);
        col1.add(new Date());
        col1.add(new String("Tom"));
        col1.add(new Student("Jarry"));
        //获取添加元素的个数
        System.out.println(col1.size());

        //addAll()
        Collection col2 = new ArrayList();
        col2.add("aa");
        col2.add(123);
        col2.add(new Date());
        col1.addAll(col2);

        System.out.println(col1.size());
        System.out.println(col1);

        //clear()清空集合元素
        col1.clear();

        //isEmpty()判断集合是否为空
        System.out.println(col1.isEmpty());

        //contains(Object obj):判断集合中是否包含obj
        Collection col3 = new ArrayList();
        col3.add(new String("Tom"));
        col3.add(new Student("Jarry"));
        col3.add(new Student("Jarry"));
        boolean contains = col3.contains("aa");
        System.out.println("--------------------------------");
        System.out.println(col3.contains(new String("Tom")));
        System.out.println(col3);
        System.out.println(new Student("Jarry"));
        System.out.println(col3.contains(new Student("Jarry")));//false --->重写equals方法true

        //containsAll(Collection col4):判断形参col4中的所有元素是否都存在于当前集合中
        System.out.println("------------------------------------");
        Collection col4 = Arrays.asList(123,456);
        System.out.println(col3.containsAll(col4));

        System.out.println("------------------------------------");
        //remove(Object obj):
        Collection col5 = new ArrayList();
        col5.add("aa");
        col5.add(123);
        col5.add(new Date());
        col5.add(new String("Tom"));
        col5.add(new Student("Jarry"));

        col5.remove("aa");//true删除成功 false删除失败
        col5.remove(new String("Tom"));
        col5.remove(new Student("Jarry"));

        System.out.println(col5);
        System.out.println("------------------------------------");
        //removeAll(Collection col1):从当前集合中移出col1中的所有元素
        Collection coll1 = Arrays.asList(123,"aa");
        col5.removeAll(coll1);
        System.out.println(col5);
    }

    @Test
    public void test2(){
        Collection col1 = new ArrayList();

        col1.add("aa");
        col1.add(123);
        col1.add(new Date());
        col1.add(new String("Tom"));
        col1.add(new Student("Jarry"));

        Collection col2 = Arrays.asList(123,"bbb",new String("Tom"));
        //col1.retainAll(Collection col2):取交集,并返回给当前集合
        col1.retainAll(col2);
        System.out.println(col1);

        //equals(Object obj):比较当前对象和形参对象中的元素是否全部相等
        Collection col3 = new ArrayList();

        col3.add(123);
        col3.add(new String("Tom"));
        System.out.println(col3.equals(col1));

    }

    @Test
    public void test3(){
        Collection col1 = new ArrayList();

        col1.add("aa");
        col1.add(123);
        col1.add(new Date());
        col1.add(new String("Tom"));
        col1.add(new Student("Jarry"));
        //hashCode():返回当前对象的哈希值
        System.out.println(col1.hashCode());

        //toArray()集合转换为数组
        Object[] objects = col1.toArray();
        for (int i = 0; i < objects.length; i++) {
            System.out.println(objects[i]);
        }

        //Arrays.asList(objects)数组转换为集合
        System.out.println(Arrays.asList(objects));

        System.out.println(Arrays.asList(new int[]{123,456}));//[[I@5e8c92f4]
        System.out.println(Arrays.asList(123,456));//[123, 456]
        System.out.println(Arrays.asList(new Integer[]{123,456}));//[123, 456]

        //iterator():返回Iterator接口的实例,用于遍历集合元素
    }

}
2.Iterator迭代器
使用Iterator接口
     Iterator对象称为迭代器(设计模式的一种),用于遍历Collection集合中的元素
     GOF给迭代器模式定义为:提供一种方法访问一个容器(Collection)对象中各个元素
     而不需要暴露该对象的内部细节。迭代器模式,就是为容器而生。
public class MethodIteratorTest {

    @Test
    public void test1(){
        Collection col1 = new ArrayList();
        //add(Object e)
        col1.add("aa");
        col1.add(123);
        col1.add(new Date());
        col1.add(new String("Tom"));
        col1.add(new Student("Jarry"));
		
        //Iterator迭代器接口
        //方式一
        Iterator it = col1.iterator();
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());//System.out.println(it.next());

        //方式二
//        for (int i = 0; i < col1.size(); i++) {
//            System.out.println(it.next());
//        }

        //方式三
        while (it.hasNext()){
            System.out.println(it.next());
        }

    }

}
3.for-each
	@Test
    public void test3(){
        String[] arr = new String[]{"MM","MM","MM"};
        //普通for循环   "GG"
//        for (int i = 0; i < arr.length; i++) {
//            arr[i] = "GG";
//        }

        //for(元素类型 局部变量 :集合对象)
        //内部调用迭代器
        //foreach循环   "MM"
        for (String str: arr ) {
            str = "GG";
        }

        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

    @Test
    public void tset1(){
        Collection list = new ArrayList();
        list.add(12);
        list.add(142);
        list.add(512);
        list.add(112);
        list.add(122);
        list.forEach(System.out::println);
    }

2.Collection实现类

1.List
1.Collection接口:单列集合
     List接口:储存有序的,可重复的数据-----“动态”数组,替换原有的数组
         ---ArrayList:线程不安全,效率高,底层用Object[] elementDate存储
         ---LinkedList:对于频繁的插入,删除,此类效率高,底层使用双向链表储存
         ---Vector:线程安全,效率低,底层用Object[] elementDate存储
2.ArrayList源码分析:
		 jdk7情况下:
         ArrayList list = new ArrayList();空参构造器创建长度是10个Object[] elementDate数组
         list.add()..//如果此次的添加导致底层elementDate数组容量不够,则扩容
                       默认情况下,扩容为原来的容量的1.5倍,同时要将原有的数据复制到新的数组中
                      结论:开发中使用带参数的构造器,ArrayList al = new ArrayList(50);
         jdk8情况下:
         ArrayList list = new ArrayList();此时的底层Object[] elementDate数组初始化为{}
         并没有创建长度为10的数组
         list.add()//第一次调用add()操作,底层才创建了长度10的数组,并添加数据,后续扩容不变
2.2小结:jdk7类似于单例的饿汉式,jdk8类似于单例的懒汉式,延迟了数组的创建时间,节省内存
3.LinkedList源码分析:
        LinkedList list = new LinkedList();内部声明了Node类型的first和last属性,默认值为null
         list.add()//将123封装到Node中,创建了Node对象
          其中Node的定义,体现了LinkedList的双向链表结构
          private static class Node<E> {
             E item;
             Node<E> next;
             Node<E> prev;

             Node(Node<E> prev, E element, Node<E> next) {
                  this.item = element;
                  this.next = next;
                  this.prev = prev;
             }
          }
4.Vector源码分析:
          jdk7和jdk8中通过Vector()构造器创建对象,底层都创建长度为10的数组
          在扩容方面,扩容到原来的两倍
小结:Vector是线程安全,但是ArrayList可以通过Collections类的synchronizedList()方法变成线程安全的
5.ArrayList常用方法
         增 add(E element)
         删 remove(Object o)/remove(int index)
         改 set(int index, E element)
         查 get(int index)
         插 add(int index, E element)
         长度 size()
         遍历 ①Iterator
             ②foreach
             ③普通循环
例题:ArrayList,LinkedList,Vector三者的异同?
同:都实现了List接口,存储数据的特点相同:有序,可重复
public class ListTest {
    //List的常用方法
    @Test
    public void test1(){
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(333);
        list.add("aa");
        list.add(new Student("Tom"));
        list.add(123);

        //add(int index, E element)在index位置插入元素
        list.add(1,"BB");

        //addAll(Collection<? extends E> c)元素整体加入
        //addAll(int index, Collection<? extends E> c)从index位置开始将元素加入
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        list.addAll(list1);
        System.out.println(list.size());

        //get(int index)获取对应位置的元素
        System.out.println(list.get(0));

        //indexOf(Object o)返回元素首次出现的位置
        System.out.println(list.indexOf(333));

        //lastIndexOf(Object o)从后往前返回首次出现的位置
        System.out.println(list.lastIndexOf(333));

        //remove(Object o)按照对象元素删除
        //remove(int index)按照脚标删除
        list.remove("aa");
        list.remove(3);

        //set(int index, E element)修改指定位置的元素
        list.set(1,"cc");

        //subList(int fromIndex, int toIndex)找到一个左闭右开的子集合,不会影响集合本身
        list.subList(1,5);
        System.out.println("-------------------------");
        //遍历1.
        Iterator it = list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        System.out.println("-------------------------");
        //2.
        for (Object obj: list
             ) {
            System.out.println(obj);
        }
        System.out.println("-------------------------");
        //3.
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }

}
2.Set
1.Collection接口:单列集合
     Set接口:存储无序的,不可重复的
            --HashSet:线程不安全,可以存储null值,底层数组
            --LinkedHashSet:HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍历
            --TreeSet:底层“红黑树”,要求:添加同一类对象,按照指定属性进行排序,
2.Set:无序,不可重复
     1.无序性:不等于随机性,存储的数据在底层数组中并非按照数组索引的顺序添加,根据数据的hashcode值决定
     2.不可重复性:保证添加的元素按照equals()方法判断时,不能返回true,即,相同的元素只能添加一个
3.HashSet添加元素的过程
     先调用hashcode()计算哈希值,通过算法计算确定在底层数组中存放位置
     然后判断此位置元素:如果此位置没有元素,则添加成功
       如果此位置有其他元素,则比较hash值
         --如果hash值不相同,则添加成功
         --如果值不相同,进而需要调用元素所在类的equals()方法:equals()确定添加的值和原有的值是否相同
                 --equals()返回true添加失败
                 --equals()返回false添加成功
         --如果hashcode值相同但是元素的值不相同,则使用链表结构指向新的元素,这样减少相同值比较的个数
                 --jdk7:新元素指向原有的元素
                 --jdk8:原有的元素指向新元素
4.注意:Set中没有额外的新方法,使用的是Collection中的方法
5.要求:Set中添加的数据,其所在的类一定要重写hashcode()和equals()
     重写的hashcode()和equals()尽可能保持一致性,相等的UI想必须具有相等的散列码(hashcode值)
public class SetTest {
    @Test
    public void test1(){
        Set<Object> hs = new HashSet<>();//jdk数组长度16
        hs.add(456);
        hs.add("ccc");
        hs.add(323);
        hs.add(new Student("Tom"));
        hs.add(new Student("Tom"));
        hs.add("cds");
        hs.add(false);

        Iterator it = hs.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

    }

    @Test
    public void test2(){
        //LinkedHashSet作为HashSet的子类
        //添加时也遵循无序性,但是通过双向链表结构记录添加前一个后一个数据,记录了添加顺序
        //对于比较频繁的遍历操作,效率高于HashSet
        HashSet<Object> hs = new LinkedHashSet<>();
        hs.add(456);
        hs.add("ccc");
        hs.add(323);
        hs.add(new Student("Tom"));
        hs.add(new Student("Tom"));
        hs.add("cds");
        hs.add(false);

        Iterator it = hs.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

    }

    @Test
    public void test3(){
        //向treeset中添加数据,要求是同一个类的数据
        //特点:有序,查询快
        //2.两种的排序方式:自然排序和定制排序
        //自然排序中如果想要比较完名字比较年龄
        //自然排序比较两个对象是否相同的标准是:compareTo()返回0,不在是equals
//        @Override
//        public int compareTo(Object o) {
//            if(o instanceof Student){
//                Student stu = (Student)o;
//                int compare =  this.name.compareTo(stu.name);
//                  if(compare != 0){
//                        return compare;
//                  }else{
//                      return Integer.compare(this.age,stu.age);
//                  }
//            }else{
//                throw new RuntimeException("输入的数据类型不匹配");
//            }
//        }

        TreeSet<Object> hs = new TreeSet<>();
        //ClassCastException
//        hs.add(456);
//        hs.add("ccc");
//        hs.add(323);
//        hs.add(new Student("Tom"));
//        hs.add(new Student("Tom"));
//        hs.add("cds");
//        hs.add(false);

//        hs.add(123);
//        hs.add(22);
//        hs.add(11);
//        hs.add(21);
//        hs.add(5);
//
//        Iterator it = hs.iterator();
//        while (it.hasNext()){
//            System.out.println(it.next());
//        }

        hs.add(new Student("Tom"));
        hs.add(new Student("jarry"));
        hs.add(new Student("bom"));
        hs.add(new Student("soul"));
        hs.add(new Student("soul"));

        //自然排序 实现comparable接口重写compareTo方法
        Iterator it = hs.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }

    }

    @Test
    public void test4(){
        Comparator co = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof Student && o2 instanceof Student){
                    Student stu1 = (Student)o1;
                    Student stu2 = (Student)o2;
                    boolean boo = stu1.getName().equals(stu2.getName());
                    if (boo){
                        return 0;
                    }else {
                        return 1;
                    }
                }else{
                    throw new RuntimeException("输入的数据类型不匹配");
                }
            }
        };
        TreeSet<Object> hs = new TreeSet<>();
        hs.add(new Student("Tom"));
        hs.add(new Student("jarry"));
        hs.add(new Student("bom"));
        hs.add(new Student("soul"));
        hs.add(new Student("soul"));

        Iterator it = hs.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
    }
}
public class Student implements Comparable{
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "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 Objects.equals(name, student.name);
    }

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

    //按照姓名从小到大排序
    @Override
    public int compareTo(Object o) {
        if(o instanceof Student){
            Student stu = (Student)o;
            return this.name.compareTo(stu.name);
        }else{
            throw new RuntimeException("输入的数据类型不匹配");
        }
    }
}
//Set添加细节
public class SetTest {
    @Test
    public void test1(){
        Set set = new HashSet();
        Person p1 = new Person(1001,"AA");
        Person p2 = new Person(1002,"BB");
        set.add(p1);
        set.add(p2);
        System.out.println(set);
        //[Person{id=1002, name='BB'}, Person{id=1001, name='AA'}]
        p1.name = "CC";
        System.out.println(set);
        //[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}]
        set.add(new Person(1001,"CC"));
        System.out.println(set);
        //[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}, Person{id=1001, name='CC'}]
        set.add(new Person(1001,"AA"));
        System.out.println(set);
        //[Person{id=1002, name='BB'}, Person{id=1001, name='CC'}, Person{id=1001, name='CC'}, Person{id=1001, name='AA'}]
    }
}
class Person{
    int id;
    String name;

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

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

3.Map

1.HashMap
1.Map:双列数据,存储key-value对的数据
     HashMap:(主要使用)线程不安全,效率高,可以存储null的key和value
          LinkedHashMap:保证在遍历map元素时,可以按照添加顺序实现遍历
                  原因:在原有的HashMap底层结构基础上,添加了一对只恨,指向前一个和后一个的元素
                  对于频繁的遍历操作,此类执行效率高于HashMap
     TreeMap:保证按照添加的key-value对进行排序,实现排序遍历,此时考虑key的自然排序或定制排序
             底层使用的是红黑树,
     Hashtable:(不常用)线程安全,效率低,不能储存null的key和value
     Properties:常用来处理配置文件,key和value都是String类型

HashMap底层数据:数组+链表(jdk7及之前)
                数组+红黑树(jdk8)

2.Map的结构理解key-value
 	Map中的key是无序的,不可重复的,使用Set存入所有的key----key所在的类要重写equals()和hashCode()以			HashMap为例
	Map中的value:无序的,可重复的,使用Collection存储所有的value
	一个键值对:key-value构成一个Entry对象,key-value是Entry的两个属性<k,v>
	Map中的entry:无序的,不可重复的,使用Set存储所有的entry
	
3.HashMap的底层实现原理?以jdk7为例说明:
HashMap map = new HashMap();
在实例化以后,底层创建了长度是16的一维数组Entry[] table.
...多次添加
map.put(key1,value1);
首先,调用key1所在类的hashcode()计算key1哈希值,得到Entry数组中的存放位置,
    如果此位置数据为null,key1和value1(entry)添加成功   ---情况1
    如果此位置数据不为空,(意味着此位置存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多		 个数据的哈希值,
         如果哈希值与其他的都不相同,此时添加成功  ---情况2
         如果哈希值和已经存在的某一个相同,继续调用key1的equals()进行比较,不相同则添加成功  ---情况3
             ,相同将使用value1替换相同key的value值(等同于修改value值)
补充:情况2和情况3:此时key1和value1和原来的数据以链表的方式储存
      在不断添加的过程中,会设计扩容的问题,超出临界值(且存放的位置非空),
      默认的扩容方式,扩容为原来容量的2倍,并将原有的数据复制过来
 
4.jdk8相比较于jdk7底层实现方面的不同
①.new HashMap():底层没有创建一个长度为16的数组
②.jdk8底层的数组是:Node[],而非Entry[]
③.首次调用put()方法时,底层创建长度为16的数组
④.jdk7底层结构只有:数组+链表,jdk8中底层结构:数组+链表+红黑树
    当数组的某一个索引位置上的元素以链表形式存在的个数 > 8 且当前数组长度 > 64 时
    此时此索引位置上的所有数据改为使用红黑树储存
DEFAULT_INITIAL_CAPACITY= 1 << 4:HashMap的默认容量,16
DEFAULT_LOAD_FACTOR = 0.75f:HashMap的默认加载因子
threshold:扩容的临界值,=容量*填充因子:16*0.75 => 12
TREEIFY_THRESHOLD = 8 :Bucket中链表长度大于该默认值,转化为红黑树
MIN_TREEIFY_CAPACITY = 64 :桶中的Node被树化时最小的hash表容量

5.总结方法
    添加:put()
    删除:remove()
    修改:put()
    查询:get()
    长度:size()
    遍历:keySet() / values() / entrySet()
例题:
①.HashMap的底层实现原理
②.HashMap和Hashtable的异同
③.CurrentHashMap和Hashtable的异同
public class MapTest {
    @Test
    public void test1(){
        Map map = new HashMap();
        map.put(123,"aa");
        map.put(234,"ab");
        map.put(345,"ac");
        System.out.println(map);
        Map map1 = new LinkedHashMap();//相比较于HashMap记录了添加的顺序
        map1.put(123,"aa");
        map1.put(234,"ab");
        map1.put(345,"ac");
        System.out.println(map1);
    }
    /**
     * Description:常用方法
     * author: Chen
     * date: 2020/10/30 21:27
     * return:
     */
    @Test
    public void test2(){
        Map map = new HashMap();
        //put()
        //添加
        map.put(123,"aa");
        map.put(234,"ab");
        map.put(345,"ac");
        //修改
        map.put(123,"bb");
        System.out.println(map);
        System.out.println("---------------");

        Map map1 = new HashMap();
        map1.put(2222,"ww");
        map1.put(111,"cc");

        //putAll()
        map.putAll(map1);
        System.out.println(map);
        System.out.println("---------------");

        //remove():按照key移除
        Object val = map.remove(123);
        System.out.println(val);
        System.out.println(map);
        System.out.println("---------------");

        //clear():清空
        map.clear();
        System.out.println(map);

    }

    /**
     * Description:元素查询操作
     * author: Chen
     * date: 2020/10/30 21:36
     * return:
     */
    @Test
    public void test3(){
        Map map = new HashMap();
        map.put(123,"aa");
        map.put(234,"ab");
        map.put(345,"ac");

        //get()
        System.out.println(map.get(123));

        //containsKey():判断key是否存在
        System.out.println(map.containsKey(123));

        //containsValue()
        System.out.println(map.containsValue("aa"));

        //isEmtry():是否为空
        System.out.println(map.isEmpty());

        //equals()
        Map map1 = new HashMap();
        map1.put(123,"aa");
        map1.put(234,"ab");
        map1.put(345,"ac");
        System.out.println(map.equals(map1));
    }

    /**
     * Description: 遍历Map
     * author: Chen
     * date: 2020/10/30 21:40
     * return:
     */
    @Test
    public void test4(){
        Map map = new HashMap();
        map.put(123,"aa");
        map.put(234,"ab");
        map.put(345,"ac");

        //keySet()
        Set key = map.keySet();
        Iterator iterator = key.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("----------------");
        //遍历value
        Collection value = map.values();
        for (Object obj: value) {
            System.out.println(obj);
        }
        System.out.println("----------------");
        //entrySet():遍历key-value
        Set set = map.entrySet();
        Iterator iterator1 = set.iterator();
        while (iterator1.hasNext()){
            Object obj = iterator1.next();
            Map.Entry entry = (Map.Entry)obj;
            System.out.print(entry.getKey() + ":");
            System.out.println(entry.getValue());
        }
        System.out.println("----------------");
        //方式二
        Set key1 = map.keySet();
        Iterator iterator2 = key1.iterator();
        while (iterator2.hasNext()){
            Object keyObj = iterator2.next();
            Object valueObj = map.get(keyObj);
            System.out.println(keyObj + ":" + valueObj);
        }
    }
}
2.TreeMap
public class TreeMapTest {
    /*
     * 向TreeMap中添加key-value,要求key必须是由同一个类创建的对象
     * 因为要按照key进行排序,自然排序,定制排序
     */
    @Test
    public void test1(){
        TreeMap map = new TreeMap();
        Student1 stu = new Student1("Tom",15);
        Student1 stu1 = new Student1("Jarry",32);
        Student1 stu2 = new Student1("Jack",14);
        Student1 stu3 = new Student1("Rose",23);
        map.put(stu,32);
        map.put(stu1,23);
        map.put(stu2,45);
        map.put(stu3,55);
        //自然排序
        Set set = map.entrySet();
        Iterator iterator1 = set.iterator();
        while (iterator1.hasNext()){
            Object obj = iterator1.next();
            Map.Entry entry = (Map.Entry)obj;
            System.out.print(entry.getKey() + ":");
            System.out.println(entry.getValue());
        }
    }
    @Test
    public void test2(){
        TreeMap map = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof Student1 && o2 instanceof Student1){
                    Student1 s1 = (Student1)o1;
                    Student1 s2 = (Student1)o2;
                    return Integer.compare(s1.getAge(),s2.getAge());
                }
                throw new RuntimeException("输入的类型不匹配");
            }
        });
        Student1 stu = new Student1("Tom",15);
        Student1 stu1 = new Student1("Jarry",32);
        Student1 stu2 = new Student1("Jack",14);
        Student1 stu3 = new Student1("Rose",23);
        map.put(stu,32);
        map.put(stu1,23);
        map.put(stu2,45);
        map.put(stu3,55);

        Set set = map.entrySet();
        Iterator iterator1 = set.iterator();
        while (iterator1.hasNext()){
            Object obj = iterator1.next();
            Map.Entry entry = (Map.Entry)obj;
            System.out.print(entry.getKey() + ":");
            System.out.println(entry.getValue());
        }
    }
}

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

    public Student1() {
    }

    public int getAge() {
        return age;
    }

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

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

    public Student1(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student1{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student1 student1 = (Student1) o;
        return age == student1.age &&
                Objects.equals(name, student1.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    //按照姓名从小到大排序
    @Override
    public int compareTo(Object o) {
        if(o instanceof Student1){
            Student1 stu = (Student1)o;
            return this.name.compareTo(stu.name);
        }else{
            throw new RuntimeException("输入的数据类型不匹配");
        }
    }
}
3.CurrentHashMap
CurrentHashMap多线程高并发的数组应用,多个线程同时操作集合中分段的数据
是由Segment数组、HashEntry组成,和HashMap一样,仍然是数组加链表。

4.Collections

reverse(List):反转List中元素的顺序
shuffle(List):对list集合元素进行随机排列
sort():排序,实现comparable接口
sort(comparator):定制排序
swap()交换指定两个位置的元素
max(list):找最大值
max(list,Compareator):按照指定顺序返回最大元素
min(list):找最小值
min(list,Compareator):按照指定顺序返回最小元素
frequency(list,object)返回list中和643相同的第一个元素的脚标
Arrays.asList():将数组转换为集合
Collections.copy(dest,list)将list集合复制进入dest集合
Collections.synchronizedXxx()方法将集合转换为线程安全的并返回
public class CollectionsTest {
    @Test
    public void test(){
        List list = new ArrayList();
        list.add(123);
        list.add(53);
        list.add(643);
        list.add(643);
        list.add(643);
        list.add(163);
        list.add(12);
        System.out.println(list);
        //reverse(List):反转List中元素的顺序
        Collections.reverse(list);
        System.out.println(list);
        //shuffle(List):对list集合元素进行随机排列
        Collections.shuffle(list);
        System.out.println(list);
        //sort():排序,实现comparable接口
        //sort(comparator):定制排序

        //swap()交换指定两个位置的元素
        Collections.swap(list,2,1);
        System.out.println(list);
        //max(list):找最大值
        //max(list,Compareator):按照指定顺序返回最大元素
        //min(list):找最小值
        //min(list,Compareator):按照指定顺序返回最小元素
        System.out.println(Collections.max(list));

        //frequency(list,object)返回list中和643相同的第一个元素的脚标
        System.out.println(Collections.frequency(list,643));
		//List dest = new ArrayList();情况一:会产生异常
        //Arrays.asList():将数组转换为集合
        List dest = Arrays.asList(new Object[list.size()]);
        //Collections.copy(dest,list)将list集合复制进入dest集合
        Collections.copy(dest,list);//IndexOutOfBoundsException情况一
        System.out.println(dest);

        //Collections.synchronizedXxx()方法将集合转换为线程安全的并返回
        List list1 = Collections.synchronizedList(list);
    }
}

5.Properties

public class PropertiesTest {
    public static void main(String[] args) throws IOException {
        //Properties:常用来处理配置文件,key和value都是string类型
        Properties pros = new Properties();
        FileInputStream is = new FileInputStream("jdbc.properties");
        pros.load(is);//加载流对应的文件

        String name = pros.getProperty("name");
        String passWord = pros.getProperty("password");
        System.out.println(name + ":" + passWord);
    }
}
public class CollectionTest {
    public static void main(String[] args) {
        //与配置文件对应的一个类
        Properties p = new Properties();
//        File file = new File("F:/idea-workspace/propertiestest/src/account.properties");
        //默认的路径是项目的src路径下 而不是模块中的src
        File file = new File("propertiestest/src/account.properties");
        try {
            InputStream is = new FileInputStream(file);
            //将配置文件加载进来,参数需要一个输入流
            p.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //直接通过key值访问对应的内容
        String pass1 = p.get("userbirth").toString();
        String pass2 = p.get("userpass").toString();
        System.out.println(pass1 + "  " + pass2);

        //使用当前类的类字节码加载器“反射”,读取文件为输入流
        //文件的路径默认从src目录下寻找
        Properties p1 = new Properties();
        InputStream is1 = CollectionUtil.class.getClassLoader().getResourceAsStream("account.properties");

        try {
            p1.load(is1);
        } catch (IOException e) {
            e.printStackTrace();
        }

        String pass3 = p1.get("userbirth").toString();
        System.out.println(pass3);
    }
}
import java.io.*;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Set;

/**
 * @author: chen
 * @date: 2020/10/21 11:23
 * @description:试着做一个collection工具类
 * @function:
 */
public class CollectionUtil {

    public static void main(String[] args) {
        CollectionUtil.saveKey("boy","123456");
        System.out.println(CollectionUtil.getValue("boy"));
        System.out.println("============================================");
        //枚举类获取到Properties里的key值 现在不常用被迭代器取代
        Enumeration em = p.keys();
        while (em.hasMoreElements()) {
            Object obj = em.nextElement();
            System.out.println(obj + "=" + p.getProperty(obj.toString()));
        }
        System.out.println("==============================");
        Set set = p.keySet();
        for (Object obj : set) {
            System.out.println(obj + "=" + p.getProperty(obj.toString()));
        }

    }

    private static final String FILEPATH = "propertiestest/src/account.properties";
    private static Properties p;

    /**
     * Description:初始化配置文件,输入文件的路径读取并加载
     * author: Chen
     * date: 2020/10/21 11:44
     * return:
     */
    static {
        p = new Properties();

        InputStream is1 = CollectionUtil.class.getClassLoader().getResourceAsStream("account.properties");

        try {
            p.load(is1);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Description: 获取输入的键对应的值
     * author: Chen
     * date: 2020/10/21 11:44
     * return:
     */
    public static String getValue(String key){
        return p.getProperty(key);
    }

    /**
     * Description: 设置键和对应的值
     * author: Chen
     * date: 2020/10/21 11:43
     * return:
     */
    public static void saveKey(String key,String val){
        //设置属性
        OutputStream os = null;
        try {
            p.setProperty(key,val);
            os = new FileOutputStream(new File(FILEPATH));
            p.store(os,"new wirte");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(os != null)
                    os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值