包装类
1.包装类 基本数据类型的引用类型
byte------->Byte
short------>Short
int-------->Integer
char------->Character
除了int和char 其他首字母大写
2.装箱和拆箱
装箱是把基本数据类型转换成包装类类型
拆箱 把包装类类型转换成基本数据类型
集合
在编程时,可以使用数组来保存多个对象。使用数组的缺点是数组的长度不可变化,一旦初始化了
数组的长度时,这个数组的长度就无法进行改变。如果想要保存数量在变化的数据时 ,使用数组的方法就不可取了。
一、Collection集合
Collection接口中声明的方法:
public boolean add(E e):把给定的对象添加到当前集合中。
public void clear() :清空集合中所有的元素。
public boolean remove(E e): 把给定的对象在当前集合中删除。
public boolean contains(E e): 判断当前集合中是否包含给定的对象。
public boolean isEmpty(): 判断当前集合是否为空。
public int size(): 返回集合中元素的个数。
public Object[] toArray(): 把集合中的元素,存储到数组中。
1、Collection的子接口——List接口
是最常用的接口。是有序集合,允许有相同的元素。使用 List 能够精确地控制每个元素插入的位
置,用户能够使用索引(元素在 List 中的位置,类似于数组下标)来访问 List 中的元素,与数组类
似。
//List:接口 extends Collection 是collection的子接口,存储的元素是有序的且可以重复 /* List的实现类 1.ArrayList:底层是基于数组实现 特点:查询快.增删慢 2.LinkedList:底层是基于链表(双向链表)实现 特点:查询慢,增删块 3.Vector:底层也是数组,线程安全,效率比ArrayList低 */
list集合中的特有方法:
① public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。
② public E get(int index):返回集合中指定位置的元素。
③ public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
④ public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值为更新前的
元素。
(1).ArrayList
java.util.ArrayList 是大小可变的数组的实现,存储在内的数据称为元素。此类提供一些方法来操作
内部存储的元素。 ArrayList 中可不断添加元素,其大小也自动增。
(2)ArrayList的声明
格式: ArrayList 名称=new ArrayList<>();
E:表示泛型:表示该集合要存储哪种引用类型的数据。如果要存储字符串就写为
ArrayList<Integer> list = new ArrayList<>();
(3)ArrayList类的基本方法
1.public boolean add(E e):往集合中添加元素,默认添加到尾部。
2.public int size():返回集合中的元素个数
3.public E remove(int index或者Object obj):删除指定下标的元素或者元素,返回删除的值
4.public E get(int index):返回指定下标的值
(4)List集合的遍历
//1.for循环遍历 使用get方法 for (int i=0;i<strlist.size();i++){ //使用get(int index)方法根据下标获取元素 System.out.println(strlist.get(i)); }
//2.增强for循环 for (String str:strlist) { System.out.println(str); }
//3.使用迭代器遍历 //1.使用iterator()方法生成Iterator对象 Iterator<String> iterator = strlist.iterator(); //2.调用iterator中的hasNext()方法 判断是否还有下一个元素 while (iterator.hasNext()){ //3.调用iterator中的next方法返回元素 System.out.println(iterator.next()); }
//4.jdk1.8新特性使用forEach遍历 strlist.forEach(item->{ System.out.println(item); });
(5)LinkedList
LinkedList集合数据存储的结构是链表结构。方便元素添加、删除。是一个双向链表。
LinkedList集合提供了大量首尾操作的方法(特有):
① public void addFirst(E e) :将指定元素插入此列表的开头。
② public void addLast(E e) :将指定元素添加到此列表的结尾。
③ public E getFirst() :返回此列表的第一个元素。
④ public E getLast() :返回此列表的最后一个元素。
⑤ public E removeFirst() :移除并返回此列表的第一个元素。
⑥ public E removeLast() :移除并返回此列表的最后一个元素。
⑦ public E pop() :从此列表所表示的堆栈处弹出一个元素。
⑧ public void push(E e) :将元素推入此列表所表示的堆栈。
⑨ public boolean isEmpty() :如果列表不包含元素,则返回true。
总结:
1.当需要对数据进行大量的查询时,使用ArrayList,底层是数组实现,查询快,增删慢。
2.当需要对数据进行大量的增删操作时,使用LinkedList,底层是链表实现,增删快,查询慢。
2、Collection的子接口——Set接口
同样继承自 Collection 接口,它与 Collection 接口中的方法基本一致,并没有对 Collection 接口进
行功能上的扩充,只是比 Collection 接口更加 严格了。与 List 接口不同的是, Set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。
//Set集合 接口,存储元素的顺序是无序的,不允许存储重复.无法通过索引去操作元素,没有索引 /* 1.HashSet 哈希表+链表+红黑树 2.TreeSet 二叉树 一般用于排序 3.LinkedHashSet 哈希表+链表+红黑树 */
1.HashSet
特点:
1.不允许存储重复的元素。
2.没有索引,没有带索引操作的方法,所以不能使用普通的for循环进行遍历。
3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致。
4.底层是一个哈希表结构。(查询速度非常快)。
注:HashSet是根据对象的哈希值来缺点元素在集合中的存储位置,因此具有良好的存储和查找性
能。保证元素唯一性的方式依赖于:hashcode和equals方法。
(1)HashSet的声明
//1.声明一个String类型的HashSet HashSet<String> hash=new HashSet<>();
(2)HashSet元素的唯一性
//1.声明一个String类型的HashSet HashSet<String> hash=new HashSet<>(); hash.add("wwww"); hash.add("ssss"); hash.add("ssss"); hash.add("bbbb"); System.out.println(hash);//[ssss, wwww, bbbb]打印出来的元素是不重复的
存储逻辑:
首先计算出存储元素元素的hash(比如123),去集合中查询是否已经存储了hash值为123的这个元素。如果没有则直接添加,如果已经存在,使用equals方法去比较存储的内容是否相同,相同则不添加,不相同则在相同hash值存储元素的下方使用链表进行存储。
(1)HashSet存储自定义类型的元素
创建people类
public class Peopel implements Comparable<Peopel>{ private String name; private int age; public Peopel() { } public Peopel(String name, int age) { this.name = name; this.age = 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 "{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Peopel peopel = (Peopel) o; return age == peopel.age && Objects.equals(name, peopel.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public int compareTo(Peopel o) { // return o.age-this.age;//按年龄大小升序排序 int i=o.name.length()-this.name.length(); //如果长度相等 if (i==0){ //按年龄升序来排 i=this.age-o.age; } return i; }
public class PeopleTest { public static void main(String[] args) { HashSet<Peopel> p=new HashSet<>(); p.add(new Peopel("素霞默哀",18)); //下面两个对象,地址不同所以hashCode不同,所以在存储时直接存储 p.add(new Peopel("wwww",18)); p.add(new Peopel("wwww",18)); System.out.println(p); //如何保证,名字和年龄一样时 hashcode不进行存储 /* 1.name和age一样时 ,返回的hashcode一样 2.判断name和age相同时 返回true */ }
如何保证对象元素的唯一?
解决:重写hashcode方法
思路:因为在存储时只是计算new People()对象的hash值,每个对象地址不一致,因此hashCode肯定也不一致,HashSet是直接存储的。是跟成员变量的值无关的。但是我们可以通过重写使用name和age两个成员变量来计算其hashcode,此时hashcode的值就和成员变量有关。
总结:对象的name和age一样时,让对象的hashcode一样,不让HashSet直接存储。
//重写equals和hashCode方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Peopel peopel = (Peopel) o; return age == peopel.age && Objects.equals(name, peopel.name); } @Override public int hashCode() { return Objects.hash(name, age); }
总结:如果要保证存储对象的唯一性。根据HashSet存储元素时的判断,就必须同时重写hashCode和equals方法。保证equlas不同时,hashCode不同。
(3)、TreeSet
TreeSet会对存储的元素进行自动排序。
TreeSet<Integer> treeSet=new TreeSet<>(); treeSet.add(1); treeSet.add(5); treeSet.add(3); treeSet.add(8); treeSet.add(4); System.out.println(treeSet);//[1, 3, 4, 5, 8] TreeSet<String> treeSet1=new TreeSet<>(); //按首字母排序 treeSet1.add("www"); treeSet1.add("aaa"); treeSet1.add("bbb"); System.out.println(treeSet1);//[aaa, bbb, www]
(4)set集合的遍历
由于Set集合没有索引,没有带索引操作的方法,所以不能使用普通的for循环进行遍历。
1.使用增强for循环遍历。
2.使用iterator迭代器进行遍历。
3.使用jdk1.8新特性进行遍历。
//使用增强for循环遍历 for (String str:hash) { System.out.println(str); } //使用迭代器遍历 Iterator<String> iterator = hash.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } //使用新特性遍历 hash.forEach(sss->{ System.out.println(sss); }); }
3、Collections工具类
常用方法
1.public static boolean addAll(Collection,T....element),往集合里面添加一些元素
2.public static void shuffle(List<?> list):打乱集合顺序
3.public static void sort(List list):将集合中元素按照默认规则排序
4.public static void sort(List list,Comparator<? super T> ) :将集合中元素按照
4、比较器--Comparator接口
根据上述代码,使用sort方法是对元素默认进行升序排列,如何按照降序进行排序。这就需要使用
Comprator比较器自定义规则。
使用方法:public static void sort(List list,Comparator<? super T> )
ArrayList<Peopel> list=new ArrayList<>(); list.add(new Peopel("苏晓茂",20)); list.add(new Peopel("苏帅晓茂",19)); list.add(new Peopel("超级无敌金刚暴龙神",25)); System.out.println(list); //使用匿名内部类创建Comparator接口的对象,并重写compara方法。 Comparator<Peopel> comparator = new Comparator<Peopel>() { @Override public int compare(Peopel o1, Peopel o2) { int i = o2.getName().length()-o1.getName().length(); if (i==0){ i=o1.getAge()-o2.getAge(); } return i; } }; //调用sort方法传递Comparator对象进行排序 Collections.sort(list,comparator); System.out.println(list); //遍历集合 for (Peopel str:list) { System.out.println(str); }
比较器--comparable接口
在Student类上实现Comparable接口,并重写CompareTo方法(与上面一样)
二、Map
现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象。
1.在Collection接口中,元素都是单个存在的。
2.Map 中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以
找对所对应的值。
3.Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
//Map:是一个接口,通过键值对来进行储存数据key--value。key不可以重复 value可以重复 /* 1.HashMap 底层:哈希表+链表+红黑树 key和value都可以为null 2.TreeMap 底层:红黑树,可以通过key来排序
1、HashMap
(1)HashMap的声明和常用方法
j//声明一个HashMap HashMap<k,v> 名称=new HashMap<>() HashMap<Integer,String> map=new HashMap<>(); map.put(1,"苏晓茂"); map.put(2,"超级无敌金刚暴龙神"); map.put(3,"灭世大将军机甲暴龙"); map.put(4,"宇宙圣龙王子"); map.put(5,"wwwwwww"); System.out.println(map); //2.public V get(Object key) :根据指定的键,在Map集合中获取对应的值。 System.out.println(map.get(3)); //3.boolean containsKey(Object key) / containsValue(Object value) :判断集合中是否包含指定的键或指定的值。 System.out.println(map.containsKey(2)); System.out.println(map.containsValue("灭世大将军机甲暴龙")); //4.public V remove(Object key) : 删除指定的键所对应的键值对元素,返回被删除元素的值。 map.remove(5); //5.public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。 System.out.println(map.keySet()); //6.public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。 System.out.println(map.entrySet());
结果:
{1=苏晓茂, 2=超级无敌金刚暴龙神, 3=灭世大将军机甲暴龙, 4=宇宙圣龙王子, 5=wwwwwww} 灭世大将军机甲暴龙 true true [1, 2, 3, 4] [1=苏晓茂, 2=超级无敌金刚暴龙神, 3=灭世大将军机甲暴龙, 4=宇宙圣龙王子]
(2)HashMap插入重复的key
代码试列:
HashMap<String,Integer> map =new HashMap<>();
map.put("盖伦", 18);
map.put("赵信", 19);
map.put("嘉文四世", 20);
System.out.println(map);//{嘉文四世=20, 赵信=19, 盖伦=18}
//添加一个重复的key
map.put("盖伦", 30);
System.out.println(map);//{嘉文四世=20, 赵信=19, 盖伦=30} 此时盖伦所对应的值被后来添加
的value覆盖了
注:在hashMap中插入重复的key时,value会被后来插入的value覆盖掉。
(4)HashMap的遍历
方式一:通过key去查找,使用keySet()方法获取到一个键集合,遍历该key,再使用get(K key)方法获取值。
方式二:HashMap中-=的每个key-value是存储在Entry这个对象中。因此我们要遍历出元素,首先要先获取到每个Entry对象。使用entryset()方法就可以获取到每个Entry,再使用Entry中的getKey()和getValue()方法来获取到键和值。
HashMap<Integer,String> map=new HashMap<>(); map.put(1,"苏晓茂"); map.put(2,"超级无敌金刚暴龙神"); map.put(3,"灭世大将军机甲暴龙"); map.put(4,"宇宙圣龙王子"); map.put(5,"wwwwwww"); //1.通过keySet()方法得到map中所有键的值,再通过get(key)方法来获取值 Set<Integer> set=map.keySet(); for (Integer str:set) { System.out.println(str+":"+map.get(str)); } //2.因为map集合中,键和值都存储在Entry中,可以通过entrySet方法来获取Entry对象 再通过Entry对象来获取键和值 Set<Map.Entry<Integer,String>> entrySet=map.entrySet(); for (Map.Entry<Integer,String> entry:entrySet) { System.out.println(entry.getKey()+":"+entry.getValue()); }
(4)HashMap存储自定义类型的值
定义一个People类 :
public class People { String name; int age; public People() { } public People(String name, int age) { this.name = name; this.age = 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 "People{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
测试:
HashMap<People,String> map=new HashMap<>(); map.put(new People("苏晓茂",18),"地球"); map.put(new People("超级无敌金刚暴龙神",9999),"火星"); map.put(new People("宇宙圣龙王子",300),"宇宙"); System.out.println(map); Set<People> keySet = map.keySet(); for (People people:keySet) { System.out.println(people+map.get(people)); } //结果 {People{name='苏晓茂', age=18}=地球, People{name='宇宙圣龙王子', age=300}=宇宙, People{name='超级无敌金刚暴龙神', age=9999}=火星} People{name='苏晓茂', age=18}地球 People{name='宇宙圣龙王子', age=300}宇宙 People{name='超级无敌金刚暴龙神', age=9999}火星