java集合框架01
List 接口存储一组不唯一(可以重复),有序(插入顺序)的对象
01. ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高
通过看ArrayList的源码得知:
/** * Constructs an empty list with an initial capacity of ten. 构造一个初始容量为十的空列表 */ public ArrayList() { this(10); 调用带参的构造 参数为10 }
ArrayList创建的时候,数组初始化长度为10!
List list=new ArrayList(-1); 这句话会运行错误! 看源码得知!
/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @exception IllegalArgumentException if the specified initial capacity * is negative */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) //参数小于0!会抛出异常信息 throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; }
List list=new ArrayList(); //初始化长度为10
list.add(1);
.....
list.add(11); //这时候集合会自动扩容!返回一个新的数组长度 =原数组的长度*1.5+1
看源码得知!
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }
创建一个新闻实体类
public class News { private int id; //新闻编号 private String title; //新闻标题 @Override public String toString() { return "新闻 [编号=" + id + ", 标题=" + title + "]"; } public News() { //无参构造 super(); } public News(int id, String title) { //带参构造 super(); this.id = id; this.title = title; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public static void main(String[] args) { News news=new News(); /* * 直接输出对象 默认走Object类中的toString() * News类中重写了这个toString() 就会走本类的! */ System.out.println(news); } }
创建测试类
public class ArrayListTest { public static void main(String[] args) { List nums=new ArrayList(); nums.add(1); nums.add(1); nums.add(1); nums.add(1); System.out.println(nums.size()); /* * 创建一个ArrayList集合 * 存储不唯一(允许重复),有序的数据! * ArrayList是实现了可变大小的数组! * 随机访问和遍历的效率高! */ List list=new ArrayList(); //往集合中添加 元素(新闻对象) News news1=new News(1, "新闻1"); News news2=new News(2, "新闻2"); News news3=new News(3, "新闻3"); list.add(news1); list.add(news2); list.add(news3); //01.打印出集合的长度 System.out.println("新闻集合的大小:"+list.size()); //02.查询下标为2的新闻信息 System.out.println(list.get(2)); //03.删除下标为1的新闻 list.remove(1); //04.通过对象删除 list.remove(news3); //05.查询集合中是否包含news3 System.out.println("是否包含news3===>"+list.contains(news3)); //新增加一个对象 list.add(new News(4, "新闻4")); //06.在指定的位置新增一个对象 list.add(0, new News(5,"新闻5")); System.out.println("*************************"); //打印新闻的标题 for (int i = 0; i < list.size(); i++) { /* * 根据集合的下标获取新闻的信息 * get(int index)返回值是Object * 必须向下转型为News */ News news=(News) list.get(i); System.out.println(news.getTitle()); } System.out.println("*************************"); //07.把集合转换成数组 Object[] array = list.toArray(); for (int i = 0; i < array.length; i++) { News news=(News) array[i]; System.out.println("新闻的标题是:"+news.getTitle()); } System.out.println("*************************"); //08.通过for加强进行遍历 for (Object object : list) { News news=(News) object; System.out.println("新闻的标题是:"+news.getTitle()); } System.out.println("*************************"); /* * 09.通过迭代器iterator接口 * 001.next():获取序列中的下一个元素 * 002.hasNext():检查序列中是否还有元素 * 003.remove():删除元素 */ Iterator it = list.iterator(); //判断集合中是否有下一个元素 while(it.hasNext()){ News news=(News) it.next(); System.out.println("新闻的标题是:"+news.getTitle()); } //10.清空整个集合 list.clear(); //11.判断集合是否为空 System.out.println("集合是否为空==>"+list.isEmpty()); System.out.println(list.size()); // 0 } }
02.LinkedList:采用链表存储方式。插入、删除元素时效率比较高
public class LinkedListTest { public static void main(String[] args) { //创建一个LinkedList集合 LinkedList list=new LinkedList(); //创建几个新闻对象 News news1=new News(1, "新闻1"); News news2=new News(2, "新闻2"); News news3=new News(3, "新闻3"); News news4=new News(4, "新闻4"); //新增数据 list.add(news1); //在一个位置 list.addFirst(news2); //news2会顶替news1在集合中的位置 news1位于第2位 list.addLast(news4); //news4在第三个位置 list.add(news3); //第4个位置 //遍历整个集合 for (Object object : list) { News news=(News) object; //转换成新闻对象才能调用对应方法 System.out.println("新闻的标题:"+news.getTitle()); } //通过indexOf(Object o) 获取对象在集合中的下标 int index=list.indexOf(news4); list.remove(index);//根据下标删除对象 //看是否还包含news4 System.out.println("是否还包含news4==>"+list.contains(news4)); //删除集合中的第一个元素 list.removeFirst(); for (Object object : list) { System.out.println(object); //不需要强制类型转换 默认走的是重写之后的toString() } //获取集合中的第一个元素 News news=(News) list.getFirst(); System.out.println("第一个元素的新闻标题:"+news.getTitle()); //获取集合中的最后一个元素 News newsz=(News) list.getLast(); System.out.println("最后一个元素的新闻标题:"+newsz.getTitle()); } }
ArrayList和LinkedList的区别
/* * ArrayList和LinkedList的区别 * ArrayList:采用数组的形式来保存数据!这些数据被放在内存中开辟连续的空间! * 每个数据的位置都有下标! * 比如说: * 现在集合长度为50! 现在想删除下标为2的元素! * 删除之后,底层还要做什么操作? * 下标为2之后的元素都要前移?? * * 现在想在下标为3的位置 新增 元素! * 下标3的元素之后的数据全部后移?? * 所以 新增,删除效率慢! * 因为是数组结构,所以遍历,查询效率高! * * LinkedList:链表式结构!存储在集合中的每个对象都存放在相互独立的空间! * 比如说: * 现在集合长度为50! * 第1个元素记录第2个元素的位置 * 第2个元素记录第3个元素的位置 * 。。。。 * 第49个元素记录第50个元素的位置 * 我们想删除第3个元素! * 只需要让 第2个元素记录第4个元素的位置! * 之后的元素有影响吗? 没有 * * 在第2个元素和第3个元素之间新增一个元素x * 这时候只需要 第2个元素 记录x的位置 * x记录第三个元素的位置 * 新增,删除效率高! * 因为没有下标,所以查询遍历的效率低! * */
set集合
public class SetTest { /** * * Set: * 01.存贮的是唯一,无序的数据 * 02.hashSet是常用的实现类 * 03.存放的是对象的引用 * HashSet底层是hashMap实现的! * 01.hashSet在添加一个数据的时候,其实是把这个值当成hashMap的key来进行保存的! * 02.hashMap地城是通过初始化一个Entry数组来实现key,value保存数据的! * 03.hashMap中的Entry有四个属性变量! key value next hash * 04.在hashMap中添加数据的步骤 * 001.对key的hashCode进行hash运算,得到的值就是对应的index * 002.判断index所指向的数组元素是否为空,如果为空,直接插入数据 * 003.如果不为空,依次查询entry中的next所指定的元素, * 判断key是否相等,如果相等,直接覆盖 * 004.如果key不相等,通过next变量将值插入Entry数组中 * */ public static void main(String[] args) { Set set = new HashSet(); set.add("1"); set.add(new String("1")); System.out.println(set.size()); // 1 } }
public class SetTest { public static void main(String[] args) { /* * Set接口存储的是唯一(不能重复),无序(新增,删除,查询)对象的集合! * HashSet是Set常用的实现类 * Set存放的是对象的引用 */ //创建一个Set集合 Set s=new HashSet(); //给集合赋值 s.add(""); //空串 s.add(null); //空值 s.add(new String("abc")); System.out.println(s.size()); // 3 Set set=new HashSet(); set.add(new News(1, "新闻1")); set.add(new News(2, "新闻2")); set.add(new News(3, "新闻3")); System.out.println(set.size()); //3 for (Object object : set) { System.out.println(object); } Set set1=new HashSet(); set1.add(new String("abc")); set1.add(new String("abc")); set1.add(new String("abc")); System.out.println(set1.size()); //1 String a ="abc"; String b =new String("abc"); String c =new String("abc"); System.out.println(a==b); //false System.out.println(c==b); //false //具有相同内容的String对象,hashCode是一致的! System.out.println(b.hashCode()==c.hashCode()); //T String str1="a"; String str2=new String("a"); System.out.println(str1==str2); //false 内存地址不一样 System.out.println(str1.equals(str2)); //true 内容一样 System.out.println(str1.hashCode()==str2.hashCode()); //T } }
public class TreeTest { public static void main(String[] args) { /* * 1. HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key * 2. Map的key和Set都有一个共同的特性就是集合的唯一性.TreeMap更是多了一个排序的功能. * 3. hashCode和equal()是HashMap用的, 因为无需排序所以只需要关注定位和唯一性即可. * 4. 由于TreeMap需要排序,所以需要一个Comparator为键值进行大小比较. */ Set set1=new HashSet(); set1.add("z"); set1.add("a"); set1.add("y"); set1.add("b"); for (Object object : set1) { System.out.println(object); } System.out.println("*******************"); TreeSet set2=new TreeSet(); //自动排序 set2.add("z"); set2.add("a"); set2.add("y"); set2.add("b"); for (Object object : set2) { System.out.println(object); } } }
map集合
public class MapTest { public static void main(String[] args) { /* * Map 是一个键值对的集合 有 key和 value * 通过key拿到value的值 * Set中的add()默认底层走的是Map的put() * 所以key是不允许重复的! * 也是先判断对象的hashCode,之后equals比较! */ Map m=new HashMap(); m.put("1", "嘘"); m.put("1", "嘘"); m.put("1", "嘘"); m.put(new String("1"), "嘘"); System.out.println(m.size()); // 1 System.out.println("*************************"); /* * 在集合中 不存在 基本数据类型 * 基本数据类型不是类! * 只能使用基本数据类型的封装类! */ Map map=new HashMap(); News news3=new News(3, "新闻3"); //向集合中增加数据 map.put("1", new News(1, "新闻1")); //这里的 "1" 是String map.put(2, new News(2, "新闻2")); //这里的2 是 Interger map.put(3, news3); map.put(4, new News(4, "新闻4")); System.out.println("集合的大小:"+map.size()); // 4 //通过map集合中的key取得对应的value News news = (News) map.get("1"); System.out.println(news); //根据key删除指定的对象 System.out.println("删除的返回值:"+map.remove(4)); //判断是否存在某个key System.out.println("是否有某个key:"+map.containsKey(4)); //判断是否存在某个value System.out.println("是否有某个value:"+map.containsValue(news3)); //得到所有key的集合 Set keySet = map.keySet(); for (Object object : keySet) { System.out.println(object); } //返回所有values的集合 Collection values = map.values(); for (Object object : values) { System.out.println(object); } } }