1.内存层面需要针对多个数据进行存储,此时,可以考虑的容器有:数组,集合类



Collection:

retainAll方法是:保留原集合和coll的交集
方法测试:
public class CollectionTest {
/*
添加方法
add(Object obj)
addAll(Collection other)
*/
@Test
public void test1() {
Collection c1 = new ArrayList();
//add
c1.add(1);
c1.add("AA");
c1.add("尚硅谷");
c1.add(new Object());
c1.add(new Person("妄竹", 19));
System.out.println(c1);
}
@Test
public void test2() {
/*
int size():获取实际存储的元素个数
boolean isEmpty():判断当前集合是否为空集合
boolean contains(Object obj):判断当前集合中是否存在一个与obj对象equals返回true的元素
boolean containsAll(Collection c):判断c集合中的元素是否在当前集合中都存在,即c集合是否是当前集合的子集
boolean equals(Object obj):判断当前集合与obj是否相等
*/
Collection c1 = new ArrayList();
//add
c1.add(128);
c1.add("AA");
c1.add("尚硅谷");
c1.add(new Object());
c1.add(new Person("妄竹", 19));
//isEmpty()
System.out.println(c1.isEmpty());//false
//contains
System.out.println(c1.contains("AA"));//true
System.out.println(c1.contains(128));//true
}
@Test
public void test3() {
/*
void clear():清空集合元素
boolean remove(Object obj):从当前集合中删除第一个找到的与obj对象equals返回true的元素,就是删除指定元素
boolean removeAll(Collection c):从当前集合中删除所有与c集合中相同的元素,
boolean removeAll(Collection coll):从当前集合中删除两个集合中不同的元素,使得当前集合只保留与c集合中的元素相同的元素
*/
Collection c1 = new ArrayList();
//add
c1.add(1);
c1.add("AA");
c1.add("尚硅谷");
c1.add(new Object());
c1.add(new Person("妄竹", 19));
System.out.println(c1);
c1.clear();
System.out.println(c1);//[]
System.out.println(c1.size());//0
}
/*
Object[] toArray():返回包含当前集合中所有元素的数组
hashCode():获取集合对象的哈希值
iterator();返回迭代器对象,用于集合遍历
*/
@Test
public void test4(){
Collection c1 = new ArrayList();
//add
c1.add(1);
c1.add("AA");
c1.add("尚硅谷");
c1.add(new Object());
c1.add(new Person("妄竹", 19));
System.out.println(c1);
Object[] arr = c1.toArray();//集合变数组
System.out.println(Arrays.toString(arr));
}


上面剩的一个方法:Iterator:用于遍历集合

public class InteratorTest {
@Test
public void test1(){
Collection c1 = new ArrayList();
//add
c1.add(1);
c1.add("AA");
c1.add("尚硅谷");
c1.add(new Object());
c1.add(new Person("妄竹", 19));
//获取迭代器
Iterator iterator1 = c1.iterator();
// //用方法next()
// for(int i = 0; i < c1.size(); i++) {
// System.out.println(iterator1.next());
// }
//用hasNext():hasNext返回的是一个boolean,用于判断有没有下一个元素
while(iterator1.hasNext()){
System.out.println(iterator1.next());
}
}
}
增强for循环:

public class Fortest {
@Test
public void test(){
Collection c1 = new ArrayList();
//add
c1.add(1);
c1.add("AA");
c1.add("尚硅谷");
c1.add(new Object());
c1.add(new Person("妄竹", 19));
for(Object object: c1){
System.out.println(object);
}
}
}
流程:
从要遍历的数组或集合中,轮流把数组或集合的元素赋给临时变量,然后操作临时变量输出

List接口常用方法测试:



方法测试:
public class ListTest {
@Test
public void test1() {
List list = new ArrayList();
list.add("AA");
list.add(123);
list.add("BB");
list.add(new Person("Tom", 12));
System.out.println(list);
list.add(2, "cc");
System.out.println(list);
List list1 = Arrays.asList(1, 2, 3);
list.addAll(1, list1);
//list.add(1,list1);// 将list1整体作为一个元素,插入索引1的位置 [AA, [1, 2, 3], 1, 2, 3, 123, cc, BB, Person{name='Tom', age=12}]
System.out.println(list);
// //这个表示删除索引为2的值
// list.remove(2);
// System.out.println(list);
//删除数据2
list.remove(Integer.valueOf(2));
System.out.println(list);
}
@Test
public void test3(){
List list = new ArrayList();
list.add("AA");
list.add(123);
list.add("BB");
list.add(2);//自动装箱
list.add(new Person("Tom", 12));
//遍历方式1:使用迭代器
Iterator iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//遍历方式2:
for(Object o:list){
System.out.println(o);
}
//一般的循环
for(int i = 0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
List不同实现类的对比以及练习:

练习1:

public class ListTest {
public static void main(String[] args) {
List list = new ArrayList();
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生信息");
while(true){
System.out.println("1:继续输入,0:结束输入");
int selection = sc.nextInt();
if(selection == 0){
break;
}
System.out.println("请输入学生姓名:");
String name = sc.next();
System.out.println("请输入学生年龄:");
int age = sc.nextInt();
Student student = new Student(name, age);
list.add(student);
}
//遍历信息
System.out.println("遍历学生信息");
for(Object student:list){
System.out.println(student);
}
sc.close();
}
}
练习2:

方法:
public class ListMethod {
public static int listTest(Collection list, String s) {
int i = 0;
for (Object o : list) {
if (s.equals(o)) {
i++;
}
}
return i;
}
}
测试:
public class ListTest2 {
public static void main(String[] args) {
List list = new ArrayList();
int aCount = 0, bCount = 0 , cCount = 0 , dCount = 0 ,eCount =0;
for (int i = 0; i < 30; i++) {
list.add((char) (Math.random() * (122 - 97 + 1) + 97) + "");
aCount = listTest(list, "a");
bCount = listTest(list, "b");
cCount = listTest(list, "c");
dCount = listTest(list, "d");
eCount = listTest(list, "e");
}
System.out.println(list);
System.out.println("a:" + aCount);
System.out.println("b:" + bCount);
System.out.println("c:" + cCount);
System.out.println("d:" + dCount);
System.out.println("e:" + eCount);
}
}
Set不同实现类的对比:


Set中无序性和不可重复性的理解:

TreeSet的使用:

例题:
public class User implements Comparable {
private String name;
private int age;
public User() {
}
public User(int age, String name) {
this.age = age;
this.name = name;
}
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 boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
//按照年龄来比
@Override
public int compareTo(Object o) {
if(this == o){
return 0;
}
if(o instanceof User){
User u = (User)o;
return this.age - u.age;
}
throw new RuntimeException("类型不匹配");
}
}
public void test2() {
TreeSet treeSet1 = new TreeSet();
User u1 = new User(19, "妄竹");
User u2 = new User(133, "妄菊");
User u3 = new User(23, "妄水");
User u4 = new User(23, "妄草");
User u5 = new User(43, "妄花");
User u6 = new User(465, "妄汐霜");
User u7 = new User(46, "妄梅");
treeSet1.add(u1);
treeSet1.add(u2);
treeSet1.add(u3);
treeSet1.add(u4);
treeSet1.add(u5);
treeSet1.add(u6);
treeSet1.add(u7);
Iterator iterator = treeSet1.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}//User{name='妄竹', age=19}
//User{name='妄水', age=23}
//User{name='妄花', age=43}
//User{name='妄梅', age=46}
//User{name='妄菊', age=133}
//User{name='妄汐霜', age=465}
}
}
如果只按年龄来比,会发现有一个年龄相同的没进去,这是因为TreeSet比较元素的大小就是比较自然排序或者定制排序的返回值的大小,如果返回值是0,那么TreeSet就会认为这两个是相等的,TreeSet中不能存放两个相同的元素,所以后一个不会进去。
如果要改变例子中的输出结果,只需要改变判断标准就行
改写后的判断标准以及输出:
public class User implements Comparable {
private String name;
private int age;
public User() {
}
public User(int age, String name) {
this.age = age;
this.name = name;
}
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 boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
//按照年龄来比
// @Override
// public int compareTo(Object o) {
// if(this == o){
// return 0;
// }
// if(o instanceof User){
// User u = (User)o;
// return this.age - u.age;
// }
// throw new RuntimeException("类型不匹配");
// }
@Override
public int compareTo(Object o) {
if (this == o) return 0;
if(o instanceof User){
User u = (User)o;
int value = this.age - u.age;
if(value != 0){
return value;
}else{
return -this.name.compareTo(u.name);//从大到小
}
}
throw new RuntimeException("类型不匹配");
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public void test2() {
TreeSet treeSet1 = new TreeSet();
User u1 = new User(19, "妄竹");
User u2 = new User(133, "妄菊");
User u3 = new User(23, "妄水");
User u4 = new User(23, "妄草");
User u5 = new User(43, "妄花");
User u6 = new User(465, "妄汐霜");
User u7 = new User(46, "妄梅");
treeSet1.add(u1);
treeSet1.add(u2);
treeSet1.add(u3);
treeSet1.add(u4);
treeSet1.add(u5);
treeSet1.add(u6);
treeSet1.add(u7);
Iterator iterator = treeSet1.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
// }User{name='妄竹', age=19}
// User{name='妄草', age=23}
// User{name='妄水', age=23}
// User{name='妄花', age=43}
// User{name='妄梅', age=46}
// User{name='妄菊', age=133}
// User{name='妄汐霜', age=465}
}
}
此时就是我们想要的结果了
上面这题再用定制排序:
@Test
public void test3(){
Comparator comparator = new Comparator() {
public int compare(Object o1, Object o2) {
if(o1 instanceof User && o2 instanceof User){
User u1 = (User) o1;
User u2 = (User) o2;
int value = u1.getName().compareTo(u2.getName());
if(value != 0){
return value;
}else{
return -(u1.getAge() - u2.getAge());
}
}
throw new RuntimeException("类型不匹配");
}
};
User u1 = new User(19, "妄竹");
User u2 = new User(133, "妄菊");
User u3 = new User(23, "妄水");
User u4 = new User(23, "妄草");
User u5 = new User(43, "妄花");
User u6 = new User(465, "妄汐霜");
User u7 = new User(46, "妄梅");
TreeSet t1 = new TreeSet(comparator);
t1.add(u1);
t1.add(u2);
t1.add(u3);
t1.add(u4);
t1.add(u5);
t1.add(u6);
t1.add(u7);
Iterator iterator = t1.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
先比姓名,再比年龄
练习1:

public class SetExer {
public static List duplicateList(List list) {
//方式1:
// Set set = new HashSet();
// for(Object obj : list){
// set.add(obj);
// }
// List list1 = new ArrayList();
// for(Object obj : set){
// list1.add(obj);
// }
// return list1;
//方式二;
Set set = new HashSet(list);
List newList = new ArrayList(set);
return newList;
}
public static void main(String[] args) {
List list = new ArrayList();
list.add(34);
list.add(44);
list.add(23);
list.add(33);
list.add(23);
list.add(33);
list.add(23);
list.add(2345);
list.add(345);
list.add(45);
list.add(64);
list.add(43);
list.add(33);
list.add(55);
List newList = duplicateList(list);
System.out.println(newList);
}
}
练习2:

public class SetExer2 {
public static void main(String[] args) {
Set set = new HashSet();
for(int i = 0;set.size() < 10; i++) {
int num = (int) (Math.random() * (20 - 1 + 1) + 1);
set.add(num);
}
System.out.println(set);
}
}
Map不同实现类的对比:

Hashtable那条笔记有误:不可以添加null的key或value值

map中常用方法:


/*
测试map中的方法
*/
@Test
public void test3(){
HashMap map = new HashMap();
//添加方法
map.put("tom",23);
map.put(67,"Tom");
map.put(new Person("妄竹",19),56);
map.put("AA",56);
map.put("BB",78);
System.out.println(map);
System.out.println(map.size());
//remove
// map.remove("AA");
//
// System.out.println(map);
//修改方法
Object oldValue = map.put("AA",88);
System.out.println(oldValue);//会输出原来的value值
System.out.println(map);
//get方法
Object value1 = map.get(67);
System.out.println(value1);
}
@Test
public void test4(){
//遍历key集,Set keySet()
Map map = new HashMap();
map.put("AA",56);
map.put("tom",23);
map.put("BB",78);
map.put(new Person("Mark",16),56);
Set set = map.keySet();
Iterator iterator = set.iterator();
while(iterator.hasNext()){
Object key = iterator.next();
System.out.println(key);
}
//遍历value集:Collection values()
Collection values = map.values();
//用增强for循环
for(Object o:values){
System.out.println(o);
}
//遍历entry集
Set entrySet = map.entrySet();
Iterator iterator1 = entrySet.iterator();
while(iterator1.hasNext()){
Map.Entry entry = (Map.Entry) iterator1.next();
System.out.println(entry.getKey() + "--->" + entry.getValue());
//System.out.println(iterator1.next());//简单一点就直接这样写
}
}

public void test3(){
Comparator comparator = new Comparator(){
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof User && o2 instanceof User){
User u1 = (User) o1;
User u2 = (User) o2;
int value = u1.getName().compareTo(u2.getName());
if(value != 0){
return value;
}else{
return u1.getAge() - u2.getAge();
}
}
throw new RuntimeException("类型不匹配");
}
};
TreeMap map = new TreeMap(comparator);
User u1 = new User(19, "妄竹");
User u2 = new User(133, "妄菊");
User u3 = new User(23, "妄水");
User u4 = new User(23, "妄草");
User u5 = new User(43, "妄花");
User u6 = new User(465, "妄汐霜");
User u7 = new User(46, "妄梅");
map.put(u1,34);
map.put(u2,68);
map.put(u3,89);
map.put(u4,43);
map.put(u5,76);
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
(User类要实现对应的接口,comparable或者comparator)

先不练,涉及到流的问题,等到后面再回头来看
练习1:

public class MapExer {
@Test
public void test1(){
Map map = new HashMap();
String singer1 = "赵一鸣";
String singer2 = "陶喆";
String singer3 = "孙燕姿";
List list1 = new ArrayList();
list1.add("退后");
list1.add("黑色毛衣");
list1.add("暗号");
List list2 = new ArrayList();
list2.add("普通盆友");
list2.add("流沙");
List list3 = new ArrayList();
list3.add("绿光");
list3.add("欧若拉");
map.put(singer1,list1);
map.put(singer2,list2);
map.put(singer3,list3);
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry entry = (Map.Entry)iterator.next();
System.out.println(entry.getKey() + " : " + entry.getValue());
}
}
}
练习2:
public class MapTest {
class CityMap {
static Map personMap = new HashMap();
public static Map model = new HashMap();
static {
model.put("北京", new String[]{"北京"});
model.put("沈阳", new String[]{"沈阳", "盘锦", "铁岭", "丹东", "大连", "锦州"});
model.put("长春", new String[]{"长春", "延边", "吉林", "白山", "白城", "四平", "松原"});
model.put("河北", new String[]{"承德", "沧州", "邯郸", "形态", "潭山", "保定", "南唐", "信箱"});
}
}
public static void main(String[] args) {
//1.获取Map集,并遍历map中所有的key
Map map = CityMap.model;
Set provinces = map.keySet();
for (Object key : provinces) {
System.out.print(key + "\t\t");
}
//2.根据提示,从键盘获取省份
Scanner sc = new Scanner(System.in);
String[] city;
System.out.println();
while (true) {
System.out.println("请选择你所在的城市");
String province = sc.next();
city = (String[]) map.get(province);
if (city == null || city.length == 0) {
System.out.println("你输入的省份有误,请重新输入");
} else {
break;
}
sc.close();
}
for (int i = 0; i < city.length; i++) {
System.out.println(city[i]);
}
//3.从键盘获取城市,遍历String数组,判断输入的城市是否在此数组中
Scanner sc1 = new Scanner(System.in);
l:while (true) {
System.out.println("请输入你的城市");
String city1 = sc1.next();
for (int i = 0; i < city.length; i++) {
if (city[i].equals(city1)) {
System.out.println(city[i]);
System.out.println("信息登记完毕");
break l;
}
}
sc1.close();
System.out.println("输入的城市有误");
}
}
}
Collections工具类:


方法测试;
public class Test1 {
@Test
public void test1(){
/*
排序操作:
reverse(List):反转list中的元素
shuffle(List):对list集合元素进行随机排序
sort(List):根据元素的自然顺序对指定list集合元素按升序排序
sort(list,Comparator):根据指定的Comparator产生的顺序对List集合元素进行排序
swap(List,int,int):将指定list集合中的i处元素和j处元素进行调换
*/
List list = Arrays.asList(25, 345, 656, 32453, 6, 25, 36, 14, 56, 124, 5, 1234, 2435);
System.out.println(list);
Collections.reverse(list);
System.out.println(list);
Collections.shuffle(list);
System.out.println(list);
Collections.sort(list);//这是因为int类型实现了comparable接口,实现了自然排序,所以直接按照升序的顺序排列了
System.out.println(list);
//如果要指定排序方法,就要用指定排序了
Collections.sort(list,new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Integer && o2 instanceof Integer){
Integer i1 = (Integer)o1;
Integer i2 = (Integer)o2;
return -(i1.compareTo(i2));//倒序
}throw new RuntimeException("类型不匹配");
}
});
System.out.println(list);
}
/*
Object max(Collection):根据元素的自然顺序,返回给定集合的最大值
Object man(Collection,Comparator):根据Comparator给定的顺序,返回给定集合中的最大元素
Object min(Collection)
Object min(Collection,Comparator)
int binarySearch(List list ,T key):就是二分查找
int binarySearch(List list, T key,Comparator c)
int frequency(Collection c,Object o):返回指定集合中指定元素的出现次数
*/
@Test
public void test2(){
List list = Arrays.asList(25, 345, 656, 32453, 6, 25, 36, 14, 56, 124, 5, 1234, 2435);
System.out.println(list);
Object max = Collections.max(list);
System.out.println(max);
int count = Collections.frequency(list, 25);
System.out.println(count);
}
/*
void copy(List dest,List src):将src中的内容复制到dest中
boolean raplaceAll(List list, Object oldVal, Object newVel):用新值替换list对象的所有旧值
提供了多个unmodifiableXxx()方法,该方法返回指定Xxx的不可修改的视图
添加:
boolean addAll(Collection c,T ... elements):将所有指定元素添加到collection中
同步:
Collections类中提供了多个synchronizedXxx()方法,该方法可以将指定集合包装成线程同步的集合
*/
@Test
public void test3() {
//copy方法
List src = Arrays.asList(25, 345, 656, 32453, 6, 25, 36, 14, 56, 124, 5, 1234, 2435);
//错误的写法:
//List dest = new ArrayList();//这样写会报错,因为复制元素的集合的实际元素个数,至少要比被添加的集合的相同或大
//正确的写法
List dest =Arrays.asList(new Object[src.size()]);
Collections.copy(dest, src);//这样就复制成功了
System.out.println(dest);
//unmodifiable,就是返回一个只能读不能修改的视图
List list = new ArrayList();
list.add(34);
list.add(34);
list.add(34);
Collections.unmodifiableCollection(list);
System.out.println(list);//返回的这个值能获取不能修改
//同步方法
//Collctions类中提供了多个synchronizedXxx()方法
List list1 = new ArrayList();
List list2 = Collections.synchronizedList(list1);//此时就会变成线程安全的了
Map map = new HashMap();
Map map2 = Collections.synchronizedMap(map);//map2就线程安全了
}
练习:

public class PokerTest {
public static void main(String[] args) {
String[] num = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
String[] color = {"方片", "梅花", "红桃", "黑桃"};
ArrayList list = new ArrayList();
//组成扑克
for (int i = 0; i < num.length; i++) {
for (int j = 0; j < color.length; j++) {
list.add( color[j]+ num[i]);
}
}
list.add("大王");
list.add("小王");
//洗牌
Collections.shuffle(list);
Collections.shuffle(list);
//发牌
List Jerry = new ArrayList();
List Mary = new ArrayList();
List me = new ArrayList();
List last = new ArrayList();
for (int i = 0; i < list.size(); i++) {
if(i >= list.size() - 3){
last.add(list.get(i));
} else if(i % 3 == 0){
Jerry.add(list.get(i));
}else if(i % 2 == 0){
Mary.add(list.get(i));
} else {
me.add(list.get(i));
}
}
System.out.println("Jerry" + "\n" + Jerry);
System.out.println("Mary" + "\n" + Mary);
System.out.println("me" + "\n" + me);
System.out.println("last" + "\n" + last);
}
}
企业真题:




Collection
├─ List(有序、可重复、支持索引)
│ ├─ ArrayList(底层:动态数组,查询快、增删慢)
│ ├─ LinkedList(底层:双向链表,增删快、查询慢)
│ └─ Vector(底层:动态数组,线程安全、效率低,过时)
├─ Set(无序、不可重复,去重依赖 equals/hashCode)
│ ├─ HashSet(底层:HashMap,无序,去重效率高)
│ ├─ LinkedHashSet(底层:LinkedHashMap,有序(插入顺序),去重+保序)
│ └─ TreeSet(底层:TreeMap,有序(排序顺序),去重+排序)
迭代器(Iterator)核心用法与注意事项
Collection<String> coll = new ArrayList<>();
Iterator<String> it = coll.iterator();
while (it.hasNext()) { // 判断是否有下一个元素
String elem = it.next(); // 获取下一个元素(必须在hasNext()后调用)
if (elem.equals("xxx")) {
it.remove(); // 遍历中删除元素(必须用迭代器的remove,不能用集合的remove!)
}
}
- 异常:若遍历中调用
coll.remove(elem),会抛出ConcurrentModificationException(并发修改异常)。
3万+

被折叠的 条评论
为什么被折叠?



