Java面试知识点:集合、Set、泛型、HashSet、HashMap
答案:
1.集合
集合和数组的对比小结
1,数组的长度是不可变的,集合的长度是可变的。
2 ,数组可以存基本数据蟀和引用数据类型。
集合只能存引用数据类型,如野存基本数据类型,需要存对应的包装类。
迭代器小结
• lterator<E> iterator() :创建迭代器对象,默认指向当前集合的0索引。
• boolean hasNext() :判断当前位置是否有元素可以被取出
• E next() :获取当前位置的元素,将迭代器对象移向下一个索引位置
增强for循环
增强for:简化数组和Collection集合的遍历
• 它是JDK5之后出现的,其内部原理是一个Iterator迭代器
•实现Iterable接口的类才可以使用迭代器和增强for
package com.xy;import java.util.ArrayList;
import java.util.Collection;/*** @ProjectName: day01* @Package: com.xy* @ClassName: test01* @Author: 杨路恒* @Description:* @Date: 2021/8/18 0018 10:18* @Version: 1.0*/
public class test01 {public static void main(String[] args) {Collection<String> collection=new ArrayList<>();collection.add("杨大大");System.out.println(collection);collection.add("恒大大");collection.remove("恒大大");System.out.println(collection);collection.removeIf((String s)->{return s.length()<=3;});System.out.println(collection);}
}package com.xy;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/*** @ProjectName: day01* @Package: com.xy* @ClassName: test02* @Author: 杨路恒* @Description:* @Date: 2021/8/18 0018 15:41* @Version: 1.0*/
public class test02 {public static void main(String[] args) {Collection<String> collection=new ArrayList<>();collection.add("杨大大");collection.add("恒大大");Iterator<String> iterator=collection.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}for (String s:collection) {System.out.println(s);}}
}package com.xy;import java.util.LinkedList;/*** @ProjectName: day01* @Package: com.xy* @ClassName: test03* @Author: 杨路恒* @Description:* @Date: 2021/8/18 0018 19:18* @Version: 1.0*/
public class test03 {public static void main(String[] args) {LinkedList<String> linkedList=new LinkedList<>();linkedList.add("杨大大");linkedList.add("恒大大");for (int i = 0; i < linkedList.size(); i++) {System.out.println(linkedList.get(i));}linkedList.addFirst("杨");linkedList.addLast("恒");for (String s : linkedList) {System.out.println(s);}System.out.println(linkedList.getFirst());System.out.println(linkedList.getLast());linkedList.remove(0);linkedList.removeFirst();linkedList.removeLast();for (int i = 0; i <linkedList.size() ; i++) {System.out.println(linkedList.get(i));}}
}
2.Set集合
Set集合概述和特点
Set集合特点
• 可以去除重复
• 存取顺序不一致
• 没有带索引的方法,所以不能使用普通for循环遍历,也不能通过获取索引来获取,删除Set集合里面的元素
Set集合练习
• 存储字符串并遍历
public class test04Set集合{public static void main(String[] args) {Set<String> strings=new TreeSet<>();strings.add("杨大大");strings.add("恒大大");Iterator<String> iterator = strings.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}for (String string : strings) {System.out.println(string);}TreeSet<Integer> treeSet=new TreeSet<>();treeSet.add(1);treeSet.add(2);treeSet.add(3);System.out.println(treeSet);}
}
代码如下:
public class Student implements Comparable<Student>{private String name;private int age;public Student() {}public Student(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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student o) {int i = this.age - o.age;i=i==0?this.name.compareTo(o.name):i;return i;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;return name != null ? name.equals(student.name) : student.name == null;}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}
}public class test05Set集合 {public static void main(String[] args) {/*TreeSet<Student> treeSet=new TreeSet<>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {//o1表示现在要存入的那个元素//o2表示已经存入到集合中的元素int i = o1.getAge() - o2.getAge(); //主要条件i=i==0?o1.getName().compareTo(o2.getName()):i; //次要条件return i;}});*/TreeSet<Student> treeSet=new TreeSet<>((Student o1, Student o2)->{int i = o1.getAge() - o2.getAge(); //主要条件i=i==0?o1.getName().compareTo(o2.getName()):i; //次要条件return i;});treeSet.add(new Student("杨大大",22));treeSet.add(new Student("恒大大",23));treeSet.add(new Student("路大大",23));System.out.println(treeSet);//不实现implements Comparable<Student>会报Exception in// thread "main" java.lang.ClassCastException:// com.xy.Student cannot be cast to java.lang.Comparable}
}
3.泛型
(1)泛型概述
泛型:是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型 它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?
顾名思义,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型
这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口
代码如下:
(1)泛型类:
package com.xy;public class Generic<T>{private T t;public T getT() {return t;}public void setT(T t) {this.t = t;}
}public class test06泛型 {public static void main(String[] args) {TreeSet treeSet=new TreeSet();treeSet.add("杨大大");
// treeSet.add(6);Generic<String> generic=new Generic<>();generic.setT("杨大大");Generic<Integer> generic1=new Generic<>();generic1.setT(6);System.out.println(generic.getT());System.out.println(generic1.getT());Generic1<Integer> generic11=new Generic1Impl();generic11.show(6);}
}
(2)泛型接口
public interface Generic1<T> {void show(T t);
}public class Generic1Impl implements Generic1 {@Overridepublic void show(Object o) {}
}public class test06泛型 {public static void main(String[] args) {TreeSet treeSet=new TreeSet();treeSet.add("杨大大");
// treeSet.add(6);Generic<String> generic=new Generic<>();generic.setT("杨大大");Generic<Integer> generic1=new Generic<>();generic1.setT(6);System.out.println(generic.getT());System.out.println(generic1.getT());Generic1<Integer> generic11=new Generic1Impl();generic11.show(6);}
}
(3)
public class test07泛型 {public static void main(String[] args) {List<?> list=new ArrayList<Object>();List<?> list1=new ArrayList<Number>();List<?> list2=new ArrayList<Integer>();List<? extends Number> list3=new ArrayList<Number>();List<? extends Integer> list4=new ArrayList<Integer>();List<? super Number> list5=new ArrayList<Number>();List<? super Integer> list6=new ArrayList<Integer>();}
}
4.HashSet
哈希值
哈希值(哈希码值):是JDK根据对象的地址或者属性值,算出来的int类型的整数
Object类中有一个方法可以获取对象的哈希值
• public int hashCode():根据对象的地址值计算出来的哈希值
对象的哈希值特点
• 如果没有重写hashCode方法,那么是根据对象的地址值计算出的哈希值。同一个对象多次调用hashCode()方法返回的哈希值是相同的不同对象的哈希值是不一样的。
• 如果重写了hashCode方法,一般都是通过对象的属性值计算出哈希值。
如果不同的对象属性值是一样的,那么计算出来的哈希值也是一样的。
HashSet1.7版本原理总结
• 底层结构:哈希表。(数组+链表)
• 数组的长度默认为16,加载因子为0.75
• 首先会先获取元素的哈希值,计算出在数组中应存入的索引
判断该索引处是否为null
如果是null ,直接添加
如果不是null ,则与链表中所有的元素,通过equals方法比较属性值 只要有一个相同,就不存,如果都不一样,才会存入集合。
HashSet1.8版本原理解析
底层结构:哈希表。(数组、链表、红黑树的结合体)。
当挂在下面的元素过多,那么不利于添加,也不利于查询,所以在JDK8以后, 当链表长度超过8的时候,自动转换为红黑树。
代码如下:
public class test09HashSet {public static void main(String[] args) {HashSet<String> hashSet=new HashSet<>();hashSet.add("杨大大");hashSet.add("恒大大");Iterator<String> iterator = hashSet.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}for (String s : hashSet) {System.out.println(s);}}
}public class test10HashSet {public static void main(String[] args) {HashSet<Student> hashSet=new HashSet<>();hashSet.add(new Student("杨大大",22));hashSet.add(new Student("恒大大",23));hashSet.add(new Student("杨大大",22));/*** 结论:* 如果HashSet集合要存储自定义对象,那么必须重写hashCode和equals方法。*/for (Student student : hashSet) {System.out.println(student.hashCode());}}
}
5.HashMap
代码如下:
public class test11HashMap {public static void main(String[] args) {Map<String,String> map=new HashMap<>();map.put("1","杨大大");map.put("2","恒大大");System.out.println(map);System.out.println(map.get("1"));System.out.println(map.size());Set<String> strings = map.keySet();System.out.println(strings);Collection<String> values = map.values();System.out.println(values);for (String s : strings) {System.out.println(map.get(s));}}
}public class test12HashMap {public static void main(String[] args) {Map<String,Student> map=new HashMap<>();map.put("1",new Student("杨大大",22));map.put("2",new Student("恒大大",22));Set<String> keySet = map.keySet();for (String s : keySet) {System.out.println(map.get(s));}Set<Map.Entry<String, Student>> entries = map.entrySet();for (Map.Entry<String, Student> entry : entries) {System.out.println(entry);}}
}public class test13HashMap {public static void main(String[] args) {Map<Student,String> map=new HashMap<>();map.put(new Student("杨大大",22),"西安");map.put(new Student("恒大大",22),"上海");Set<Student> keySet = map.keySet();for (Student s : keySet) {System.out.println(map.get(s));}Set<Map.Entry<Student, String>> entries = map.entrySet();for (Map.Entry<Student, String> entry : entries) {System.out.println(entry);}map.put(new Student("恒大大",22),"上海");}
}public class test14HashMap {public static void main(String[] args) {ArrayList<HashMap<String,String>> array=new ArrayList<>();HashMap<String,String> map=new HashMap<>();map.put("杨大大","22");map.put("恒大大","22");HashMap<String,String> map1=new HashMap<>();map1.put("杨大大","22");map1.put("恒大大","22");array.add(map);array.add(map1);for (HashMap<String, String> hashMap : array) {System.out.println(hashMap);}}
}