Set集合:
Set集合和List集合的区别?Set集合:不允许元素重复,唯一的(元素可以为null) ,不能保证迭代的顺序恒久不变(底层哈希表和hascode)也就是:无序(存储和取出不一致);
List集合:允许元素重复,并且存储特点:有序性(存储和取出一致;
Set集合保证唯一性的原因:
HashSet集合的add方法底层依赖于双列集合HashMap,它依赖于两个方法,HashCode()方法和equals()方法,先比较字符串的HashCode()码值一样,再比较equals()方法,如果hasCode码值一样,还要比较内容是否相同,由于存储String,重写了equals()方法;
Set集合的遍历:
举例:
public class SetDemo {
public static void main(String[] args) {
//创建Set集合对象,子实现类:HashSet集合
Set<String> set = new HashSet<String>();
//添加元素
set.add("hello") ;
set.add("java") ;
set.add("world") ;
//看他的唯一性,多存储一些元素
set.add("hello") ;
set.add("java") ;
set.add("world") ;
//遍历
for(String s: set) {
System.out.println(s);
}
}
}
Set存储自定义对象并遍历:
举例:在Set集合中使用add方法时需要重写equals()和hashCode()方法;
import java.util.HashSet;
import java.util.Set;
class Student {
private String name ;
private int age ;
public Student() {
super();
}
public Student(String name, int age) {
super();
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 int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class SetDemo3 {
public static void main(String[] args) {
Set<Student> set = new HashSet<Student>() ;
//创建学生对象
Student s1 = new Student("高圆圆", 27) ;
Student s2 = new Student("高圆圆", 28) ;
Student s3 = new Student("文章", 30) ;
Student s4 = new Student("马伊琍", 39) ;
Student s5 = new Student("高圆圆", 27) ;
//存储到集合中
set.add(s1) ;
set.add(s2) ;
set.add(s3) ;
set.add(s4) ;
set.add(s5) ;
//遍历
for(Student s : set) {
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
Set集合的子类:LinkedHashSet集合:如果在开发中,元素唯一性,并且还要保证元素有序(存储和取出一致),使用LinkedHashSet集合;
LinkedHashSet集合的特点:
1> 底层是一种链接列表和哈希表组成;
2> 可以保证元素的唯一性,是由哈希表决定的(hashCode()和equals());
3> 可以保证元素的迭代顺序一致(有序),存储和取出一致,是由链表决定;
LinkedHashList集合的遍历:
举例:
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args) {
//创建LinkedHashSet集合对象
LinkedHashSet<String> link = new LinkedHashSet<String>() ;
//添加元素
link.add("hello") ;
link.add("java") ;
link.add("world") ;
link.add("world") ;
link.add("world") ;
link.add("java") ;
//增强for遍历
for(String s: link) {
System.out.println(s);
}
}
}
TreeSet集合:如果开发中要使用集合排序的问题(在自然顺序对集合中的元素排序),使用TreeSet集合(红黑树结构);
举例:
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
//创建一个集合对象TreeSet集合对象
TreeSet<Integer> ts = new TreeSet<Integer>() ;
//给集合中存储元素
ts.add(20) ; //add()方法底层的源码是一个Map接口实例
ts.add(22) ;
ts.add(18) ;
ts.add(23) ;
ts.add(24) ;
ts.add(17) ;
ts.add(19) ;
ts.add(18) ;
ts.add(24) ;
//遍历
for(Integer i : ts) {
System.out.print(i +" ");
}
}
}
TreeSet存储自定义对象并遍历:(自然排序);
举例:
//对于自定义的类型,要实现自然排序,必须自定义的类型必须实现Comparable
//实现接口中的方法,compareTo() :比较方法
class Student implements Comparable<Student>{
private String name ;
private int age ;
public Student() {
super();
}
public Student(String name, int age) {
super();
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 int compareTo(Student s) { //源码 cmp = k.compareTo(t.key)
//根据条件写自己需要的规则,并加以判断
//按照某种规则,前提必须有这规则
//主要条件:按照年龄从小到大
int num = this.age - s.age ; //如果年龄相等,不一定是同一个人
//需要自己分析次要条件;
//年龄相同,姓名的内容不一定相同,比较姓名
int num2 = num==0 ? this.name.compareTo(s.getName()) : num ; //这里有一个方法递归
//如果年龄相同(num==0),按字典顺序比较姓名返回一个值并赋给num2,年龄不为0,则将num赋给num2;
return num2 ;
}
}
public class TreeSetDemo2 {
public static void main(String[] args) {
//创建TreeSet集合对象
TreeSet<Student> ts = new TreeSet<Student>() ;//只要是无参构造的方式就是自然排序
//创建学生对象
Student s1 = new Student("gaoyuanyuan",27) ;
Student s2 = new Student("liushishi",38) ;
Student s3 = new Student("gaoyuanyuan",28) ;
Student s4 = new Student("wanglihong",35) ;
Student s5 = new Student("wanglihong",30) ;
Student s6 = new Student("fengqingy",38) ;
Student s7 = new Student("gaoyuanyuan",27) ;
//java.lang.ClassCastException: org.westos_03.Student cannot be cast to java.lang.Comparable
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
//遍历
for(Student s:ts) {
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
TreeSet存储自定义对象并遍历:(比较器排序);
举例:
package exercise;
import java.util.Comparator;
import java.util.TreeSet;
//创建学生类
class Student{
private String name;
private int age;
public Student() {
}
Student(String name, int age) {
super();
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;
}
}
public class Text1{
public static void main(String[] args) {
//直接使用接口匿名内部类的方式实现
TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
/**
* 自然排序:Comparable 里面compareTo(Student s)
*
*this---->s1
*s---s
*/
//return 0;
//按照姓名长度进行比较
int num = s1.getName().length() - s2.getName().length() ;
//长度一样,还要比较姓名的内容是否相同
int num2 = num==0 ?s1.getName().compareTo(s2.getName()) : num ;
//最终看年龄是否一致
int num3 = num2 ==0 ? (s1.getAge() - s2.getAge()) : num2 ;
return num3 ;
}
});
//创建学生对象
Student s1 = new Student("gaoyuanyuan", 27) ;
Student s2 = new Student("zhangguorong",29) ;
Student s3 = new Student("wuqilong", 40) ;
Student s4 = new Student("liushishi", 28) ;
Student s5 = new Student("fengqingy", 29) ;
Student s6 = new Student("gaoyuanyuan", 22) ;
Student s7 = new Student("gaoyuanyuan", 27) ;
//添加对象
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;
//遍历
for(Student s:ts) {
System.out.println(s.getName()+s.getAge());
}
}
}
注意:在比较器排序和自然排序使用的接口,都一样没有什么区别,实现的功能是一样的;
实现Comparable接口不能使用匿名内部类的方式,而Compareto可以;
/**
*
* @Override
* //可以用实现接口Comparable并且重写compareTo方法;
* //也可以实现接口Comparator并且重写compare方法;
* //两种方法都一样,只是形式参数有些区别;
* public class Student implements Comparator<Student> {
*
* @Override
* public int compare(Student s1, Student s2) {
*
* int num=s1.getName().length()-s2.getName().length();
* int num2=num==0? s1.getName().compareTo(s2.getName()):num;
* int num3=num2==0? s1.getAge()-s2.getAge():num2;
* return num3;
* }
* }
*
* System.out.println("------------------------------------------------");
*
* public class Student implements Comparable<Student> {
*
* @Override
* public int compareTo(Student s) {
*
* int num=this.getName().length()-s.getName().length();
* int num2=num==0? this.getName().compareTo(s.getName()):num;
* int num3=num2==0? this.getAge()-s.getAge():num2;
* return num3;
* }
* }
*
*/
Map集合:
特点:
1> 键值的映射关系的一种集合(接口);
2> 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值;
3> Map<K,V>在Map集合中,只针对键有效,跟值无关;
4> Map接口的子实现类:HashMap和TreeMap;
面试题:
Map集合和Collection的区别?
Map集合:是一种键和值的映射关系(双列集合);
Collection集合:单列集合,只能存储一种类型的元素;
间接关系:HashSet依赖于Map接口的子实现类HashMap的;
TreeSet依赖于Map接口的子实现类TreeMap的;
V put(K key,V value):添加功能:将指定的值和键关联起来;
如果当前的这个键是一次存储,则返回值null;
如果不是第一次存储,返回值是第一次对应的值,当前的值就把之前的键对应的值替换掉;
获取功能:
Set<Map.Entry<K,V>> entrySet():和Map集合的遍历有关系(键值对对象);
Set<K> keySet():获取映射关系中所有的键的集合;
int size():返回此映射中的键-值映射关系数;
删除功能:
void clear():删除所有映射关系;
Vremove(Object key):如果存在一个键的映射关系,则将其从此映射中移除;
判断功能:
boolean containsKey(Object key):如果此映射包含指定键的映射关系,则返回 true;
boolean containsValue(Object value):映射关系中是否包含指定的值;
boolean isEmpty():判断映射关系是否为空;
举例:
public class MapDemo {
public static void main(String[] args) {
//创建Map集合对象
Map<String, String> map = new HashMap<String,String>() ;
System.out.println("map:"+map);
//添加功能的作用
//如果当前的这个键是一次存储,则返回值null
System.out.println("put():"+map.put("文章", "马伊琍"));
//如果不是第一次存储,返回值是第一次对应的值,当前的值就把之前的键对应的值替换掉!
System.out.println("put():"+map.put("文章", "***"));
//添加元素
map.put("高圆圆", "赵又廷") ;
map.put("周杰伦", "昆凌") ;
map.put("黄晓明", "babay") ;
map.put("文章", "马伊琍") ;
//V remove(Object key)如果存在一个键的映射关系,则将其从此映射中移除,返回的是该对应的值
System.out.println("remove():"+map.remove("黄晓明"));
System.out.println("map:"+map);
//boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true
System.out.println("containsKey():"+map.containsKey("杨过"));
System.out.println("containsKey():"+map.containsKey("高圆圆"));
//boolean containsValue(Object value):映射关系中是否包含指定的值
System.out.println("containsValue():"+map.containsValue("昆凌"));
System.out.println("map:"+map); //{key1=value1, key2=value2,.}
//void clear():删除所有映射关系
map.clear();
System.out.println("map:"+map);
}
}
Map集合的遍历:方法1举例:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
*
* 这种遍历方式实际开发中经常用的...
* Set<K> keySet():获取映射关系中所有的键的集合
*
* V get(Object key):通过键找值
* 转换法:
* 1)将所有的丈夫集中起来
* 2)让丈夫它对应的妻子
* 3)将他们遍历出来
*
*
* 思路:
* 1)获取所有的键的集合
* 2)通过键找它对应的值
* 3)遍历即可
*
*/
public class MapDemo2 {
public static void main(String[] args) {
//创建Map集合
Map<String,String> map = new HashMap<String,String>() ;
//添加元素
map.put("杨过", "小龙女") ;
map.put("郭靖", "黄蓉") ;
map.put("陈旋风", "梅超风") ;
map.put("高圆圆", "赵又廷") ;
//遍历
//先获取所有的键的集合
Set<String> set = map.keySet() ;
//遍历素有的键,获取每一个键
for(String key :set) {
//通过键找值
String value = map.get(key) ;
System.out.println(key+"="+value);
}
}
}
方式2举例:import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* Map集合的另一种方式的遍历 Set<Map.Entry<K,V>> entrySet() :和Map集合的遍历有关系(键值对对象)
*
* 转发法:
* 1)获取所有的结婚证
* 2)通过结婚证分别找对应的丈夫和妻子
* 3)遍历输出
*
*
* 思路:
* 1)获取所有的键值对象entrySet()
* 2) K getKey() 和 v getValue(),获取键值对对象中的每个键和每个值
* 3)遍历
*
*
*/
public class MapDemo3 {
public static void main(String[] args) {
// 创建Map集合对象
Map<String, String> map = new HashMap<String, String>();
// 添加元素
map.put("杨过", "小龙女");
map.put("郭靖", "黄蓉");
map.put("陈旋风", "梅超风");
map.put("高圆圆", "赵又廷");
//获取所有的键值对对象
Set<Map.Entry<String, String>> entrySet = map.entrySet() ;
//增强for
for(Map.Entry<String, String> entry :entrySet) {
//获取到每一个键值对对象
//通过键值对对象找键和值
String key = entry.getKey() ;
String value = entry.getValue() ;
System.out.println(key+"="+value);
}
}
}