新手初学Java集合框架
程序员文章站
2022-03-24 07:51:33
目录java集合框架list接口arraylistvectorlinkedlist:set接口hashsettreesetmap接口hashmaphashtabletreemapjava集合框架集合...
java集合框架
集合
- 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
- 集合和数组的区别:
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型。
测试
/* 1.添加 2.删除 3.遍历 4.判断 */ collection col = new arraylist(); col.add("张三"); col.add("李四"); col.add("王五"); // col.add("张三"); system.out.println(col); // col.remove("张三"); // system.out.println(col); for (object o : col) { system.out.println(o); } system.out.println("------------------"); iterator it = col.iterator(); while (it.hasnext()){ string next = (string) it.next(); system.out.println(next); } system.out.println(col.isempty()); system.out.println(col.contains("张三"));
list接口
特点:有序、有下标、元素可以重复。
可以通过角标在指定位置添加查询元素。
list list = new arraylist(); list.add("java"); list.add("c++"); list.add(1,"python"); list.add(".net"); system.out.println(list.size()); system.out.println(list.tostring()); //1.for each遍历 system.out.println("---------------"); for (object o : list) { system.out.println(o); } //2.迭代器遍历 system.out.println("---------------"); iterator iterator = list.iterator(); while (iterator.hasnext()){ system.out.println(iterator.next()); } //3.list迭代器遍历 system.out.println("--------正序-------"); listiterator listiterator = list.listiterator(); while (listiterator.hasnext()){ system.out.println(listiterator.next()); } //逆序前必须先进行正序遍历,让指针指向列表最后一个元素,才能开发遍历 system.out.println("--------逆序-------"); while (listiterator.hasprevious()){ system.out.println(listiterator.previousindex() + ":" +listiterator.previous()); }
添加数字等基本类型数据时,会进行自动装箱的操作。
删除数字元素需要通过下标来删除,或者将需要删除的数字转成object类或者该类型对应的包装类。
sublist
:返回一个子集合,含头不含尾。
list实现类
arraylist
- 数组存储结构,查询快、增删慢;
- jdk1.2版本出现,运行效率快,线程不安全。
- 源码分析:
- default_capacity = 10 默认容量 。注意:如果没有向集合中添加任何元素时,容量为0,添加一个元素之后,容量为10。每次扩容大小都是原来的1.5倍,如添加第11个元素时,容量由10变为了15。
- add()方法源码:为什么添加一个元素之后,容量为10。
public boolean add(e e) { ensurecapacityinternal(size + 1); // increments modcount!!增长修改个数 elementdata[size++] = e; return true; } private void ensurecapacityinternal(int mincapacity) { if (elementdata == defaultcapacity_empty_elementdata) { mincapacity = math.max(default_capacity, mincapacity); } ensureexplicitcapacity(mincapacity); } private void ensureexplicitcapacity(int mincapacity) { modcount++; // overflow-conscious code if (mincapacity - elementdata.length > 0) grow(mincapacity); } private void grow(int mincapacity) { // overflow-conscious code int oldcapacity = elementdata.length; int newcapacity = oldcapacity + (oldcapacity >> 1); if (newcapacity - mincapacity < 0) newcapacity = mincapacity; if (newcapacity - max_array_size > 0) newcapacity = hugecapacity(mincapacity); // mincapacity is usually close to size, so this is a win: elementdata = arrays.copyof(elementdata, newcapacity); }
- elemetndata 存放元素的数组
- size 实际元素个数
测试代码:
arraylist arraylist = new arraylist(); student s1 = new student("张三",18); student s2 = new student("李四",18); student s3 = new student("王五",18); arraylist.add(s1); arraylist.add(s2); arraylist.add(s3); system.out.println(arraylist.tostring()); //删除元素(需要重写equals方法) arraylist.remove(new student("李四",18)); system.out.println(arraylist.size()); public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return false; student student = (student) o; return age == student.age && objects.equals(name, student.name); }
vector
- 数组存储结构,查询快,增删慢;
- jdk1.0版本出现,运行效率慢、线程安全;
- 枚举器遍历
vector vector = new vector(); vector.add("java"); vector.add("python"); vector.add(".net"); system.out.println(vector.tostring()); //枚举器遍历 enumeration elements = vector.elements(); while (elements.hasmoreelements()){ system.out.println(elements.nextelement()); }
linkedlist:
- 双向链表存储结构,增删快,查询慢。
泛型:
- 时jdk1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递;
- 常见形式由泛型类、泛型接口、泛型方法;
- 好处:
- 提高代码的重用性
- 防止类型转换异常,提高代码的安全性
泛型集合:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
特点:
- 编译时即可检查,而非运行时抛出异常。
- 访问时,不必类型转换。
- 不同泛型之间引用不能相互赋值,泛型不存在多态。
set接口
特点:无序、无下标、元素不可重复
方法:全部继承自collection中的方法。
set实现类
hashset
- 存储结构:哈希表(数组+链表+红黑树)
- 基于hashcode实现元素不重复
- 根据hashcode计算保存的位置,如果此位置为空,则直接保存。如果不为空,执行下一步。
- 当存入元素的哈希码相同时,会调用equals进行确认,如果为true,则拒绝后者存入。否则,则生成链表。
public hashset(){ map = new hashmap<>(); }
测试代码:
hashset<student> set = new hashset<>(); student s1 = new student("张三",18); student s2 = new student("李四",18); student s3 = new student("王五",18); set.add(s1); set.add(s2); set.add(s3); // set.add(new student("李四",18)); system.out.println(set.size()); system.out.println(set.tostring()); // set.remove(new student("李四",18)); // system.out.println(set.size()); // system.out.println(set.tostring()); for (student student : set) { system.out.println(student); } system.out.println("===================="); iterator<student> iterator = set.iterator(); while (iterator.hasnext()){ system.out.println(iterator.next()); } public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return false; student student = (student) o; return age == student.age && objects.equals(name, student.name); } public int hashcode() { return objects.hash(name, age); }
hashcode重写方法中加入31的原因
1.31是一个质数,减少散列冲突
2.31提高执行效率
treeset
- 存储结构:红黑树
- 基于排列顺序实现元素不重复
- 实现了sortedset接口,对集合元素自动排序
- 元素对象的类型必须实现comparable接口,指定排列规则
- 通过compareto方法确定是否为重复元素
测试代码:使用treeset集合实现字符串按照长度进行排序
treeset<string> treeset = new treeset<>(new comparator<string>() { @override public int compare(string o1, string o2) { int n1 = o1.length() - o2.length(); int n2 = o1.compareto(o2); return n1==0?n2:n1; } treeset.add("zhangsan"); treeset.add("wkf"); treeset.add("asd"); treeset.add("abc"); treeset.add("ljcv"); treeset.add("lisi"); treeset.add("wang"); system.out.println(treeset.tostring()); system.out.println(treeset.size());
map接口
特点:
1.用于储存任意键值对(key,value)
2.键:无序、无下标、不允许重复
3.值:无序、无下标、允许重复
遍历:
- keyset()方法遍历:拿到key的set集合。
- entryset()方法遍历:将map封装成entry键值对集合。
测试代码:
map<string, string> map = new hashmap<>(); map.put("wkf","666"); map.put("qwe","678"); map.put("kfc","999"); map.put("asd","694"); set<string> keyset = map.keyset(); for (string s : keyset) { system.out.println(s + "=" + map.get(s)); } system.out.println("==================="); set<map.entry<string, string>> entries = map.entryset(); for (map.entry<string, string> entry : entries) { system.out.println(entry.getkey() +"=" + entry.getvalue() ); }
hashmap
- jdk1.2版本,线程不安全,运行效率快;允许用null作为key或是value。
- 构造一个具有默认初始容量16和默认加载因子0.75的空hashmap。
- 加载因子:比如当前集合容量为100,那么当数据存储到第75个位置是进行扩容操作。
- 源码分析
static final int default_initial_capacity = 1 << 4; // hashmap初始容量大小16 static final int maximum_capacity = 1 << 30;//hashmap的数组最大容量 static final float default_load_factor = 0.75f;//默认加载因子 static final int treeify_threshold = 8;//jdk1.8开始,当链表长度大于8时,调整成红黑树 static final int untreeify_threshold = 6;//jdk1.8开始,当链表长度小于6时,调整成链表 static final int min_treeify_capacity = 64;//jdk1.8开始,当链表长度大于8时,并且集合元素个数大于等于64时调整成红黑树 transient node<k,v>[] table;//哈希表中的数组
总结:
- hashmap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
- 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的两倍。目的是减少调整元素的个数
- jdk1.8开始,当链表长度大于8时,并且集合元素个数大于等于64时调整成红黑树,目的是提高执行效率
- jdk1.8开始,当链表长度小于6时,调整成链表
- jdk1.8以前,链表时头插入,jdk1.8以后是尾插入
hashtable
- jdk1.0版本,线程安全,运行效率慢;不允许null作为key或是value
- properties:
- hashtable的子类,要求key和value都是string,通常用于配置文件的读取。
treemap
- 实现了sortedmap接口(是map的子接口),可以对key自动排序。
collections工具类
- sort():升序排列
- copy():复制
- binarysearch():二分查找
- collections.binarysearch(list,需要查找的值);
- reverse():反转
- shuffle():打乱集合中的元素
- list转成数组:
- list.toarray(new integer[0]);
- 数组转成集合
- arrays.aslist(names);
- 集合是一个受限集合,不能添加 和
总结
本篇文章就到这里了,希望能给您带来帮助,也希望您能够多多关注的更多内容!