1.使用List集合去除字符串中的重复的值
import java.util.ArrayList;
import java.util.Iterator;
public class Test1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("张三");
list.add("张三");
list.add("李四");
list.add("李四");
list.add("王五");
method1(list);
System.out.println(list);// [张三, 张三, 李四, 李四, 王五]
method2(list);
}
//方式二:拿着前面的元素值和剩余的元素值进行比较,一旦发现后面的元素和前面的元素值一致,删除后面的那个元素值
private static void method2(ArrayList<String> list) {
for(int i=0; i<list.size()-1; i++){
for(int j=i+1; j<list.size(); j++){
if(list.get(i).equals(list.get(j))){
list.remove(j);
//j需要-1,因为集合的长度是动态变化的
j--;
}
}
}
System.out.println(list);//[张三, 李四, 王五]
}
// 方式一:新建一个集合,然后遍历原有的集合拿出每一个元素,判断新集合中是否包含该元素,如果不包含就添加到新集合中
private static void method1(ArrayList<String> list) {
ArrayList<String> list2 = new ArrayList<String>();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String value = iterator.next();
if (!list2.contains(value)) {
list2.add(value);
}
}
System.out.println(list2);//[张三, 李四, 王五]
}
}
2.使用Linkedlist去除集合中的重复值
public class Person {
private String name;
private int age;
private char sex;
public Person() {
super();
}
public Person(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + sex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex != other.sex)
return false;
return true;
}
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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
import java.util.Iterator;
import java.util.LinkedList;
/*
* LinkedList
去除集合中自定义对象的重复值(对象的成员变量值都相同)
数组的长度:数组名.length
String的长度:字符串.length()
集合的长度:集合.size()
*/
public class Test1 {
public static void main(String[] args) {
LinkedList<Person> list = new LinkedList<Person>();
list.add(new Person("张三", 18, '男'));
list.add(new Person("张三", 18, '男'));
list.add(new Person("王五", 18, '男'));
list.add(new Person("王五", 19, '男'));
list.add(new Person("赵六", 18, '男'));
list.add(new Person("赵六", 18, '男'));
//方式二:拿着前面的集合元素和剩余的集合元素进行比较,一旦发现相等就将后面的集合元素删除
for(int i=0; i<list.size()-1; i++){
for(int j=i+1; j<list.size(); j++){
if(list.get(i).equals(list.get(j))){
list.remove(j);
//因为集合长度是动态变化的,所以j需要-1
j--;
}
}
}
Iterator<Person> iterator = list.iterator();
while(iterator.hasNext()){
Person p = iterator.next();
System.out.println(p);
}
}
// 方式一:新建一个集合,遍历原始集合拿出每一个元素,判断新集合中是否包含当前元素,如果不包含就将元素添加到新集合中
private static void method1(LinkedList<Person> list) {
LinkedList<Person> list2 = new LinkedList<Person>();
for(int i=0; i<list.size(); i++){
Person p = list.get(i);
if(!list2.contains(p)){
list2.add(p);
}
}
for(int i=0; i<list2.size(); i++){
System.out.println(list2.get(i));
}
}
}
3.Set集合
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
/*
* Set集合:一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。
* Set集合去重的原理:
* 它是依赖元素对应的hashCode和equals方法进行去重的,存入元素的时候,首先会判断hashCode值是否和其他的元素一致,如果哈希值不一致,就说明
* 不是重复元素,直接添加;如果哈希值一致,再去调用equals方法进行判断,如果返回true就表明是重复值,不添加,如果返回false就说明不是重复值
* 就添加到集合中。
* 注意:Set集合没有通过索引操作元素的方法,而List集合有
* HashSet:哈希表结构,不保证存入和取出的顺序一致
* LinkedHashSet:哈希表+链表结构,保证存入和取出的顺手一致
*/
public class Test2 {
public static void main(String[] args) {
// Set集合存储String类型的值
Set<String> set = new HashSet<String>();// [李四, 张三, 王五]
set = new LinkedHashSet<String>();// [张三, 李四, 王五]
set.add("张三");
set.add("张三");
set.add("李四");
set.add("李四");
set.add("王五");
set.add("王五");
System.out.println(set);
// Set集合存储自定义对象
HashSet<Person> set2 = new HashSet<Person>();
set2 = new LinkedHashSet<Person>();
set2.add(new Person("张三", 18, '男'));
set2.add(new Person("张三", 18, '男'));
set2.add(new Person("李四", 18, '男'));
set2.add(new Person("李四", 18, '男'));
set2.add(new Person("张三", 18, '男'));
set2.add(new Person("xiaowang", 8, '男'));
set2.add(new Person("大王", 28, '女'));
set2.add(new Person("小王", 5, '男'));
for (Person p : set2) {
System.out.println(p);
}
}
}
public class Person {
private String name;
private int age;
private char sex;
public Person() {
super();
}
public Person(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + sex;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex != other.sex)
return false;
return true;
}
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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
4.泛型的用法和注意事项
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test3 {
public static void main(String[] args) {
// 一般泛型左右两边必须保持一致的类型
// ArrayList<Object> list = new
// ArrayList<Integer>();//因为Object和Integer都是明确的类型
/*
* 泛型通配符<?> 任意类型,如果没有明确,那么就是Object以及任意的Java类了
*/
Collection<?> c = new ArrayList<Object>();
test(new ArrayList<Object>());
c = new ArrayList<Animal>();
test(new ArrayList<Animal>());
c = new ArrayList<Dog>();
test(new ArrayList<Dog>());
c = new ArrayList<Cat>();
test(new ArrayList<Cat>());
/*
* ? extends E 向下限定,E及其子类
*/
Collection<? extends Animal> c2 = new ArrayList<Animal>();
test2(new ArrayList<Animal>());
c2 = new ArrayList<Cat>();
test2(new ArrayList<Cat>());
c2 = new ArrayList<Dog>();
test2(new ArrayList<Dog>());
// c2 = new ArrayList<Object>();Object不是Animal的子类
/*
* ? super E 向上限定,E及其父类
*/
Collection<? super Animal> c3 = new ArrayList<Animal>();
c3 = new ArrayList<Object>();
// 添加值:c3集合可以往里面添加Animal类的值,因为集合的泛型是Animal或者Animal的父类,至少可以Animal类型的值
c3.add(new Animal());
c3.add(new Cat());
// 取值:c3集合中存储的最大类型就是Object,所以取值的值必须也用Object来接收
Iterator<? super Animal> iterator = c3.iterator();
Object obj = iterator.next();
// c3 = new ArrayList<Cat>();Cat是Animal的子类
// c3 = new ArrayList<Dog>();Dog是Animal的子类
}
public static void test2(Collection<? extends Animal> c) {
// 添加值:c集合接收的集合的泛型只知道是Animal及其子类,具体的类型也不知道,所以不能添加值
// 取值:c集合存储的最大的类型就是Animal,所以可以使用Animal引用变量来接收
Iterator<? extends Animal> iterator = c.iterator();
Animal a = iterator.next();
}
public static void test(Collection<?> c) {
// 添加值:c集合接收的集合的泛型是什么类型是未知的,所以不能添加值
// 取值:不论c集合存储的是什么类型,我都可以用Object类型引用来接收
Iterator iterator = c.iterator();
Object obj = iterator.next();
}
}
class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
5.可变参数的用法和注意事项 , 数组和集合的转换
import java.util.Arrays;
import java.util.List;
/*
* 可变参数:当不知道定义多少个参数合适,可以使用可变参数,可变参数本质上是一个数组
* 注意事项:当参数列表中有可变参数并且有多个参数时,可变参数必须放在最后的位置
*/
public class Test1 {
public static void main(String[] args) {
System.out.println(getSum("", 1, 2, 3, 4, 5));// 15
// 把数组转换成集合
// public static <T> List<T> asList(T... a)返回一个受指定数组支持的固定大小的列表
Integer[] arr = { 1, 2, 3, 4, 5 };// 如果想把数组转换成集合,那么这个数组必须是引用类型的
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
System.out.println(list);// [1, 2, 3, 4, 5]
// 把集合转换成数组
/*
* <T> T[] toArray(T[] a)返回包含此 collection
* 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同 a - 存储此 collection
* 元素的数组(如果其足够大);否则,将为此分配一个具有相同运行时类型的新数组。
*/
Integer[] temp = new Integer[2];
Integer[] array = list.toArray(temp);// 如果temp数组足够大就用temp数组,如果不够大,就内部自己新建一个数组
System.out.println(Arrays.toString(array));// [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(temp));// [null, null]
System.out.println(array == temp);// false
}
public static int getSum(String msg, int... arr) {
int sum = 0;
for (int i : arr) {
sum += i;
}
return sum;
}
}
6.增强for循环的使用和注意事项
import java.util.ArrayList;
import java.util.Iterator;
/*
* 增强for循环:针对集合的遍历,内部使用的迭代器
* for(遍历的元素类型 变量名 : 要遍历的数组或集合){
* ...
* }
* 注意事项:
* 要遍历的目标不能是null
*/
public class Test4 {
public static void main(String[] args) {
String[] arr = { "哈哈", "呵呵", "嘻嘻", "嘿嘿" };
// 可以知道当前遍历的是第几个索引
for (int i = 0; i < arr.length; i++) {
String v = arr[i];
}
// 无法知道当前遍历的索引
for (String s : arr) {
System.out.println(s);
}
System.out.println("--------------------------------------");
ArrayList<String> list = new ArrayList<String>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
Object[] array = list.toArray();
Iterator<String> iterator = list.iterator();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
// list = null;
for (String s : list) {
// 内部用的是迭代器
// list.add("");//java.util.ConcurrentModificationException
System.out.println(s);
}
}
}
7.Map集合的用法和注意事项
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/*
* Map集合:将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
* 键值对结构:key=value
* 键是唯一性的,通过哈希表结构保证的,是依赖键对象的hashCode和equals方法
* 值是可以重复的
* HashMap:哈希表结构,存入和取出顺序不保证一致
* LinkedHashMap:链表+哈希表结构,保证存入和取出的顺序一致
*/
public class KillThread {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map = new LinkedHashMap<Integer, String>();
// V put(K key,V value)将指定的值与此映射中的指定键关联,返回的值是以前与 key 关联的值,如果没有针对 key
// 的映射关系,则返回 null
map.put(110, "报警电话");
map.put(120, "急救电话");
map.put(121, "急救电话");
map.put(119, "火警电话");
String value = map.put(119, "火警电话2");
System.out.println(value);// 火警电话
System.out.println(map);// {110=报警电话, 120=急救电话, 121=急救电话, 119=火警电话2}
// V remove(Object key)移除key对应的值并将之返回,如果没有key对应的值则返回null
System.out.println(map.remove(121));// 急救电话
System.out.println(map);// {110=报警电话, 120=急救电话, 119=火警电话2}
// void clear()清空map集合
// map.clear();
// System.out.println(map);//{}
// boolean containsKey(Object key)判断此map中是否包含指定的key
System.out.println(map.containsKey(110));// true
// boolean containsValue(Object value)判断此map中是否包含指定的value
System.out.println(map.containsValue("急救电话"));// true
// boolean isEmpty()判断此map集合是否为空
System.out.println(map.isEmpty());// false
// int size()返回map集合中键值对的个数
System.out.println(map.size());// 3
}
}
8.遍历map集合
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
//Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容
public class KillThread {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(110, "报警电话");
map.put(120, "急救电话");
map.put(121, "急救电话");
map.put(119, "火警电话");
System.out.println(map);// {119=火警电话, 120=急救电话, 121=急救电话, 110=报警电话}
// V get(Object key)获取键对应的值,如果没有对应的值就返回null
System.out.println(map.get(119));// 火警电话
System.out.println("----------------------------------------");
// 遍历方式一:获取所有的键值集,然后遍历每一个键,通过键获取值
// Set<K> keySet()返回此映射中包含的键的 Set 视图
Set<Integer> keySet = map.keySet();
for (Integer key : keySet) {
String value = map.get(key);
System.out.println(key + "=" + value);
}
// Collection<V> values()返回此映射中包含的值的 Collection 视图
Collection<String> values = map.values();
for (String value : values) {
System.out.println(value);
}
System.out.println("----------------------------------------");
// 方式二:获取键值对对象集合,然后遍历每一个键值对对象,然后通过键值对对象获取键和值
// Set<Map.Entry<K,V>> entrySet()返回此映射中包含的映射关系的 Set 视图
Set<Entry<Integer, String>> entrySet = map.entrySet();
for (Entry<Integer, String> entry : entrySet) {
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "=" + value);
}
}
}
9.验证对象的唯一性是由hashmap和hashset保证的
public class Student {
private String name;
private int age;
private char sex;
public Student() {
super();
}
public Student(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + sex;
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;
if (sex != other.sex)
return false;
return true;
}
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 char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
//Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
//验证键对象保持唯一性是由hashCode和equals方法保证的
public class KillThread {
public static void main(String[] args) {
Map<Student, String> map = new HashMap<Student, String>();
map = new LinkedHashMap<Student, String>();
map.put(new Student("张三", 18, '男'), "张三1");
map.put(new Student("张三", 18, '男'), "张三2");
map.put(new Student("李四", 18, '男'), "张三3");
map.put(new Student("王五", 18, '男'), "张三4");
for (Entry<Student, String> entry : map.entrySet()) {
System.out.println("key:"+entry.getKey());
System.out.println("value:"+entry.getValue());
System.out.println("-----------------------------------------");
}
}
}
10.三层嵌套+三层循环复杂结构的实现
import java.util.LinkedHashMap;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
//有一个锦囊设置了三层防护,每一层都必须通过密码来获取,请想怎么设计这个程序
public class KillThread {
public static void main(String[] args) {
String s = "要么忙着活,要么忙着死";
// 第一次防护
LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
map.put(110, s);
// 第二次防护
LinkedHashMap<Integer, LinkedHashMap<Integer, String>> map2 = new LinkedHashMap<Integer, LinkedHashMap<Integer, String>>();
map2.put(119, map);
// 第三次防护
LinkedHashMap<Integer, LinkedHashMap<Integer, LinkedHashMap<Integer, String>>> map3 = new LinkedHashMap<Integer, LinkedHashMap<Integer, LinkedHashMap<Integer, String>>>();
map3.put(120, map2);
// 用户手动输入密码
Scanner sc = new Scanner(System.in);
// 拆开最外层防护
while (true) {
System.out.println("请输入最外层防护的密码:");
int key = sc.nextInt();
LinkedHashMap<Integer, LinkedHashMap<Integer, String>> map4 = map3.get(key);
if (null != map4) {// 如果map4不是null,就说明最外层拆开成功
// 拆开第二层防护
while (true) {
System.out.println("请输入第二层防护的密码:");
key = sc.nextInt();
LinkedHashMap<Integer, String> map5 = map4.get(key);
if (null != map5) {// 如果map5不是null,就说明第二层拆开成功
// 拆开最后一层防护
while (true) {
System.out.println("请输入最后一层防护的密码:");
key = sc.nextInt();
String value = map5.get(key);
if (null != value) {
System.out.println(value);
break;
} else {
System.out.println("最后一层密码输入错误,请重新输入");
}
}
break;
} else {
System.out.println("第二层密码输入错误,请重新输入");
}
}
break;
} else {
System.out.println("最外层密码输入错误,请重新输入");
}
}
}
}
11.Compator接口的用法和注意事项
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/*
* Comparator比较器接口:不论元素对象有没有比较规则,都以Comparator的比较规则为准
* 1.覆盖元素对象的已有比较规则
* 2.如果元素对象没有比较规则,那么可以让元素对象具有比较规则
*/
public class Test1 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(0);
list.add(90);
list.add(-19);
list.add(1);
System.out.println(list);// [10, 0, 90, -19, 1]
// public static <T> void sort(List<T> list,Comparator<? super T>
// c)根据指定比较器产生的顺序对指定列表进行排序
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// o1和o2比较:升序
// return o1.compareTo(o2);
// return o1-o2;//o2大于o1返回大于0的值,o2等于o1返回0,o2小于o1返回负数
// o2和o1比较:降序
// return o2.compareTo(o1);
return o2 - o1;// o2大于o1返回大于0的值,o2等于o1返回0,o2小于o1返回负数
}
};
Collections.sort(list, comparator);// 根据comparator进行排序
System.out.println(list);// [90, 10, 1, 0, -19]
// public static <T> int binarySearch(List<? extends T> list,T
// key,Comparator<? super T> c)使用二分搜索法搜索指定列表,以获得指定对象
System.out.println(Collections.binarySearch(list, 0, comparator));// 根据comparator进行查找
}
}
12.Compatable接口的用法和注意事项
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/*
* Comparable比较器接口:自定义对象实现这个接口,就可以具有比较规则
*/
public class ComparableDemo {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<Person>();
list.add(new Person("zhangsan",18));
list.add(new Person("zhangsan",28));
list.add(new Person("wangwu",8));
list.add(new Person("zhaoliu",8));
list.add(new Person("xiaohua",20));
list.add(new Person("cuihua",10));
//列表中的所有元素都必须实现 Comparable 接口
Collections.sort(list,new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
//o1的成员变量和o2的成员变量比较:升序
//以姓名为主进行升序,如果姓名相等再以年龄为主进行升序
if(o1.getName().equals(o2.getName())){
return o1.getAge()-o2.getAge();
}else{
return o1.getName().compareTo(o2.getName());
}
//o2的成员变量和o1的成员变量比较:降序
}
});
for (Person p : list) {
System.out.println(p);
}
}
}
13.Collections的使用
import java.util.ArrayList;
import java.util.Collections;
public class Test1 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(0);
list.add(90);
list.add(-19);
list.add(1);
System.out.println(list);// [10, 0, 90, -19, 1]
// public static <T> void sort(List<T> list)根据元素的自然顺序 对指定列表按升序进行排序
Collections.sort(list);
System.out.println(list);// [-19, 0, 1, 10, 90]
// public static <T> int binarySearch(List<?>
// list,Tkey)使用二分搜索法搜索指定列表,以获得指定对象
System.out.println(Collections.binarySearch(list, 0));// 1
// public static void reverse(List<?> list)反转指定列表中元素的顺序
Collections.reverse(list);
System.out.println(list);// [90, 10, 1, 0, -19]
System.out.println(Collections.binarySearch(list, 0));// -1
// public static <T> T max(Collection<?> coll)根据元素的自然顺序,返回给定
// collection的最大元素
System.out.println(Collections.max(list));// 90
// public static <T> T min(Collection<?> coll)根据元素的自然顺序 返回给定
// collection的最小元素
System.out.println(Collections.min(list));// -19
// public static void shuffle(List<?> list)使用默认随机源对指定列表进行置换
Collections.shuffle(list);
System.out.println(list);// [1, 0, -19, 10, 90]
// 1.创建一个容器存放54张牌
ArrayList<String> list2 = new ArrayList<String>();
list2.add("大王");
list2.add("小王");
list2.add("1");
// ...
// 2.调用shuffle方法洗牌
Collections.shuffle(list2);
Collections.shuffle(list2);
Collections.shuffle(list2);
Collections.shuffle(list2);
// 3.创建三个容器代表三个人,接口扑克牌
for (int i = 0; i < list2.size(); i++) {
switch (i % 3) {
case 0:
break;
case 1:
break;
case 2:
break;
}
}
}
}
14.treeset 和treemap的使用
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
// public TreeSet()构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。插入该 set 的所有元素都必须实现
// Comparable 接口
TreeSet<Integer> set = new TreeSet<Integer>();
//public TreeSet(Comparator<? super E> comparator)构造一个新的空 TreeSet,它根据指定比较器进行排序
set = new TreeSet<Integer>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//o1和o2比较:升序
//o2和o1比较:降序
return o2-o1;
}
});
set.add(10);
set.add(0);
set.add(-10);
set.add(20);
set.add(1);
System.out.println(set);//[-10, 0, 1, 10, 20]
}
}
import java.util.Comparator;
import java.util.TreeMap;
public class TreeMapDemo {
public static void main(String[] args) {
//public TreeMap()使用键的自然顺序构造一个新的、空的树映射。插入该映射的所有键都必须实现 Comparable 接口
TreeMap<Integer,String> map = new TreeMap<Integer,String>();
//public TreeMap(Comparator<? super K> comparator)构造一个新的、空的树映射,该映射根据给定比较器进行排序
map = new TreeMap<Integer,String>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//o1和o2比较:升序
//o2和o1比较:降序
return o2-o1;
}
});
map.put(10, "哈哈");
map.put(0, "呵呵");
map.put(20, "嘿嘿");
map.put(-1, "吼吼");
map.put(5, "哼哼");
map.put(3, "嘻嘻");
System.out.println(map);//{-1=吼吼, 0=呵呵, 3=嘻嘻, 5=哼哼, 10=哈哈, 20=嘿嘿}
}
}
15.面试题
HashMap,Hashtable,ConcurrentHashMap的区别?
HashMap:线程不安全的,只适合单个线程操作;允许添加null元素
(不用了)Hashtable:线程安全的,适合多个线程操作,但是效率特别低;不允许添加null元素
ConcurrentHashMap:线程安全的,适合多个线程操作,效率相比Hashtable要高一些;不允许添加null
16.使用LinkedListSet
import java.util.LinkedHashSet;
import java.util.Random;
public class LinkedHashSetTest {
public static void main(String[] args) {
//使用LinkedHashSet编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
LinkedHashSet<Integer> set = new LinkedHashSet<Integer>();
Random r = new Random();
//判断set的长度是否小于10
while(set.size()<10){
int v = 1+r.nextInt(20);
set.add(v);
}
System.out.println(set);
System.out.println(set.size());//10
}
}
17.set集合是用法和注意事项
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
/*
* Set集合:一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。
* Set集合去重的原理:
* 它是依赖元素对应的hashCode和equals方法进行去重的,存入元素的时候,首先会判断hashCode值是否和其他的元素一致,如果哈希值不一致,就说明
* 不是重复元素,直接添加;如果哈希值一致,再去调用equals方法进行判断,如果返回true就表明是重复值,不添加,如果返回false就说明不是重复值
* 就添加到集合中。
* 注意:Set集合没有通过索引操作元素的方法,而List集合有
* HashSet:哈希表结构,不保证存入和取出的顺序一致
* LinkedHashSet:哈希表+链表结构,保证存入和取出的顺手一致
*/
public class SetDemo {
public static void main(String[] args) {
// Set集合存储String类型的值
Set<String> set = new HashSet<String>();// [李四, 张三, 王五]
set = new LinkedHashSet<String>();// [张三, 李四, 王五]
set.add("张三");
set.add("张三");
set.add("李四");
set.add("李四");
set.add("王五");
set.add("王五");
System.out.println(set);
// Set集合存储自定义对象
HashSet<Person> set2 = new HashSet<Person>();
set2 = new LinkedHashSet<Person>();
set2.add(new Person("张三", 18, '男'));
set2.add(new Person("张三", 18, '男'));
set2.add(new Person("李四", 18, '男'));
set2.add(new Person("李四", 18, '男'));
set2.add(new Person("张三", 18, '男'));
set2.add(new Person("xiaowang", 8, '男'));
set2.add(new Person("大王", 28, '女'));
set2.add(new Person("小王", 5, '男'));
for (Person p : set2) {
System.out.println(p);
}
}
}