前言
依稀记得去年三月中旬第一次真正接触集合,当时觉得天崩地裂,怎么学都是蒙的,由此,当时记录了很多笔记,在此做一个积累,便于日后添加和查阅。
1、常用的四个集合ArrayList、HashMap、HashSet和TreeSet及区别
/*
* ArrayList、HashMap、HashSet、TreeSet这四个集合的一系列运用和规律
*/
public class ExampleGather {
/*
* 泛型:泛型只在编译阶段有效,在运行阶段会去泛型化;
* 也就是说泛型只在逻辑上看不同,实际用途相同。
*
* 总结:
* ArrayList、HashMap、HashSet、TreeSet四个集合中
* 1.HashMap不能直接遍历,需要通过Set objSet = objHashMap.Keyset();之后才能遍历
* 2.TreeSet需要自定义比较方法才能输出,否则报错,
* 其中自定义的比较方法需要调用系统的串口Comparator
* 3.在输出的时候需要看每个集合中内容的类型,如果是八大基本数据类型的包
* 装类,可以直接输出(具体请看第二部分);如果是自定义的类充当类型
* (例如Student),需要如下书写规范objStudent.intNo,也就是需要
* 写出自定义类中,具体输出什么内容
*/
// ArrayList可以输出重复元素,怎么放入,怎么输出
// HashMap不可以输出重复元素,无论怎么放入,按照逻辑顺序输出
// HashSet不可以输出重复元素,无论怎样放入,按照哈希算法输出
// TreeSet不可以输出重复元素,无论怎样放入,按照我们定义的比较方法输出
// **********如果有重复元素,后面替代前面,之后按照相应集合方式输出*******************
public void getSummary() {
/*
* 集合ArrayList的定义,添加,遍历,输出
*/
/*
* 八大基本数据类型存储在栈中;String既可存储在堆中,也可存储在栈中。
* eg:String str = "abc" 栈中
* String str = new String("abc") 堆中
*/
List<String> objArrayList = new ArrayList<String>(); //这样定义也可以,后面的new才是实例化对象
objArrayList.add("a");
objArrayList.add("b");
objArrayList.add("a");
objArrayList.add(1, "c");
objArrayList.remove(2);
System.out.println("输出ArrayList1: " + " " + objArrayList); //这里数据存储在栈中,所以输出是数据
//输出ArrayList1: [a, c, a]
objArrayList.remove("a"); //按顺序先删除第一个a
objArrayList.set(0, "z");
// 一共有三种遍历方式,一二不需要迭代器,但是迭代器更好用
// 一
for (int i = 0; i < objArrayList.size(); i++) { //for()循环以数组形式输出
System.out.println("输出ArrayList2: " + " " + objArrayList.get(i));
//输出ArrayList2: z
//输出ArrayList2: a
}
// 二
for (String str : objArrayList) { //for-each()循环以数组形式输出
System.out.println("输出ArrayList3: " + " " + str); //这个循环没有下标,所以不能增删,但是速度快
//输出ArrayList3: z
//输出ArrayList3: a
}
// 三
Iterator<String> it = objArrayList.iterator(); //遍历循环输出,和for-each()循环效果一样
while (it.hasNext()) {
String str = it.next();
System.out.println("输出ArrayList4: " + " " + str);
//输出ArrayList3: z
//输出ArrayList3: a
}
/*
* 集合HashMap的定义,添加,遍历,输出,其中在遍历之前有两种
* 方法可以实现遍历,一个keySet()方法,一个entrySet()方法
*/
/*
* 在集合中,如果类型是包装类和String,则集合可以直接输出,
* 不需要遍历也不需要for,这时输出的是数据
*/
HashMap<Integer, String> objMap = new HashMap<Integer, String>();
objMap.put(1, "ly1");
objMap.put(2, "ly2");
objMap.put(1, "ly3");
objMap.put(3, "ly2");
System.out.println("输出ArrayList5: " + " " + objMap);
//输出ArrayList5: {1=ly3, 2=ly2, 3=ly2}
/*
* 利用keySet()方法实现遍历
*/
Set<Integer> objSet = objMap.keySet();
Iterator<Integer> it1 = objSet.iterator();
while (it1.hasNext()) {
int intKey = it1.next();
System.out.println("输出HashMapKeySet1: " + " " + intKey + " " + objMap.get(intKey));
//输出HashMapKeySet1: 1 ly3
//输出HashMapKeySet1: 2 ly2
//输出HashMapKeySet1: 3 ly2
}
/*
* 利用entrySet()方法实现遍历
*/
Set<Entry<Integer, String>> objSet1 = objMap.entrySet();
Iterator<Entry<Integer, String>> it2 = objSet1.iterator();
while (it2.hasNext()) {
Entry<Integer, String> objEntry = it2.next();
System.out.println("输出HashMapEntrySet2: " + " " + objEntry.getKey() + " " + objEntry.getValue());
//输出HashMapEntrySet2: 1 ly3
//输出HashMapEntrySet2: 2 ly2
//输出HashMapEntrySet2: 3 ly2
}
/*
* 集合HashSet的定义,添加,遍历,输出
*/
HashSet<String> objHashSet = new HashSet<String>();
objHashSet.add("ab");
objHashSet.add("aas");
objHashSet.add("fc");
objHashSet.add("bc");
Iterator<String> it3 = objHashSet.iterator();
while (it3.hasNext()) {
String str = it3.next();
System.out.println("输出HashSet: " + " " + str);
//输出HashSet: ab
//输出HashSet: bc
//输出HashSet: aas
//输出HashSet: fc
}
/*
* 集合TreeSet的定义,添加,遍历,输出
*/
TreeSet<Student> objTreeSet = new TreeSet<Student>(new MyCompare());
objTreeSet.add(new Student(3, "la3"));
objTreeSet.add(new Student(3, "ly1"));
objTreeSet.add(new Student(2, "ly2"));
Iterator<Student> it4 = objTreeSet.iterator();
while (it4.hasNext()) {
Student objStudent = it4.next();
System.out.println("输出TreeSet: " + " " + objStudent.intNo + " " + objStudent.strName);
//输出TreeSet: 2 ly2
//输出TreeSet: 3 la3
//输出TreeSet: 3 ly1
}
}
public static void main(String[] args) {
ExampleGather objSum = new ExampleGather();
objSum.getSummary();
}
}
class Student {
public int intNo;
public String strName;
public Student(int no, String name) {
intNo = no;
strName = name;
}
}
class MyCompare implements Comparator<Object> {
@Override
public int compare(Object arg0, Object arg1) {
Student objStu1 = (Student) arg0;
Student objStu2 = (Student) arg1;
int intResult;
// if判断语句的简便写法,其中有三个判断
intResult = objStu1.intNo > objStu2.intNo ? 1 : objStu1.intNo < objStu2.intNo ? -1 : 0;
// 系统自带的比较方法compareTo
if (intResult == 0) {
intResult = objStu1.strName.compareTo(objStu2.strName);
}
return intResult;
}
}
有关这四个集合的简单运用,代码中的注解已经标注的很清楚了,在这四个集合中,工作常用的是ArrayList和HashMap,这两者的区别尤为重要。
2、集合的输出机制
上面介绍集合的三种输出方式,for、foreach、迭代器,但在项目中最常用的是get()方法直接输出,接下来展示一段代码。
/**
* 直接输出集合的解释:
* 1.在aList集合中存储的数据类型是Point,则输出是地址,但是由于Point类中重写了toString()方法,所以输出是数据;
* 2.而如果在aList集合中存储的数据类型是八大基本数据类型的包装类或String,则输出是数据,这是因为包装类中和String中都已经重写了toString了
*
* 直接输出集合的原理:
* 1.在输出集合全部数据的时候一共调用两个toString(),第一个是为了把数据用[]包起来,第二个是调用重写的toString())
* 2.不过如果输出的是集合中第二条数据的intNumber变量的值无论是否重写toString()方法,都会输出数据,
* 这是因为intNumber变量存储在栈中,而new Point(2,2)是存储在堆中,所以前者输出是数据,后者输出是地址
*/
List<Point> aList = new ArrayList<Point>();
aList.add(new Point(1,1));
aList.add(new Point(2,2));
aList.add(new Point(3,3));
System.out.println("输出集合中全部数据:"+aList); //输出集合中全部数据:[1=1, 2=2, 3=3]
System.out.println("输出集合中第二条数据: "+aList.get(1)); //输出集合中第二条数据: 2=2
System.out.println("输出集合中第二条数据的intNumber变量的值: "+aList.get(1).intNumber); //输出集合中第二条数据的intNumber变量的值: 2
//以下是Point类
public class Point {
public int intNumber;
public int intNumber1;
public Point(int intA, int intB) {
this.intNumber = intA;
this.intNumber1 = intB;
}
// 这个方法很重要,改变了全局内容
// 因为Object中的toString()方法输出的是地址,这里重写了toString(),影响了println()返回的值,因此改变了全局
public String toString() {
return intNumber + "=" + intNumber1;
}
}
这一部分当时纠结了好久,一直不是很懂,直到多次整理笔记之后才渐渐明了,后来又做过几个项目,随着对后端了解的加深,慢慢自然就懂了。
如果看了上面的原理还不懂,请参考如下有关System.out.println()的笔记来理解
public class ExampleToString1118 {
/*
* 在Java中,所有的对象都是继承自Object,自然继承了toString方法,在当使用System.out.println()
* 里面为一个对象的引用时,自动调用toString方法将对象打印出来。 如果重写了tostring方法则调用重写的toString 方法。
*
* 因为System.out.println()的这个方法源码中调用了String.valueOf(Objec o),源码如下:
* public void println(Object x) {
* String s = String.valueOf(x);
* synchronized (this) {
* print(s); newLine();
* }
* }
*
* 而String.valueOf(x)的源码就是去调用该对象的toString()方法,源码如下:
* public static String valueOf(Object obj) {
* return (obj == null)?"null":obj.toString();
* }
*/
public static void main(String[] args) {
System.out.println(new A());
//输出我是A
//输出com.examplegather.example.A@15db9742
}
}
class A {
public A() {
System.out.println("我是A");
}
}
3、集合夯实基础练习
当时我还做过两个练习题,练习题目如下:
HashMap<HashSet<Integer>, TreeSet<Student>> objHashMap = new HashMap<HashSet<Integer>, TreeSet<Student>>();
具体就是集合嵌套集合的如何输出?要求用迭代器输出,一个要求用HashMap中的keySet()方法输出,另一个要求用HashMap中的entrySet()方法输出,这两道题比较练习基本逻辑。
题目答案的代码文档在此链接中,有兴趣的可以下载
https://download.youkuaiyun.com/download/zcy92949/10363692
4、总结
以上就是我对集合中一些基本的理解,如有不对之处,希望诸君不吝赐教。
版权声明:本文出自孤星卟哭的博客,原创文章,转载请注明出处。 https://blog.youkuaiyun.com/zcy92949/article/details/80074839