第十五篇:关于java的总结(下)
最近总感觉时间不够用,要好好珍惜时间了。这篇就把剩下的部分补充完,关于java我想给大家整理的基本也就结束后了。其实记忆是个非常不靠谱的东西,我们必须落实到笔记上,多次加以复习才能得到巩固。
java中的高级数据结构
学习这个部分,对于有数据结构知识基础的同学应该掌握起来也比较简单,唯一难受的可能就是每个集合类有很多方法,需要记忆,如果要想足够的熟练只能多使用多记忆。我唯一能给大家建议的,在记忆这些方法的时候一定要注意:集合类是为了方便我们进行数据存储和读取的,那么掌握他的方法的时候可以遵循这样的一些逻辑:(1)我集合初始化方法有哪些(可不可以通过数组直接初始化);
(2)集合的增、删、改、查 对应的方法都是什么;
(3)集合的属性查询,比如大小、是否为空 是用什么方法;
(4)集合中的元素排序要怎么实现。
在学习的时候尽量往这四个方面进行归类,然后剩下的就是大家在刷题的时候在牛客网上多练习,尽量使用java相应的高级数据结构进行实现,一方面能够快速地解决题目,另一方面也使自己进一步熟悉java集合的使用。所以刷题其实也能够帮助我们进一步地熟悉我们所掌握的编程语言。
高级数据结构的分类
java的高级高级数据结构主要分为两种,
- 一种是继承了Collection接口的集合类数据结构,
- 一种是以前的旧有的实现,如Vetcor、Stack、Dicitionary、Hashtable、Properties、BitSet、Enumeration等。
那么在java的集合类中又主要分了三大类结构:list、set和Map,其简单的特点可如下展示:
集合方法的简单分类
//数据结构初始化:
//1.初始化为空数据结构
//2.初始化为数据结构的大小以及增长因子
//增:单个增加或者批量增加元素;
//1.在数据结构的尾部增加
//2.在数据结构的指定位置增加
//3.批量增加的时候是使用别的数据结构进行增加
//删:单个删除或者批量删除元素;
//1.单个删除可以匹配具体的元素删除,或者是删除指定索引位置的元素
//2.批量删除,删除某个索引范围内的元素
//3.clear函数,清空整个数据结构
//改:单个修改或者批量修改元素;
//查:查找符合要求的单个或多个元素;
//1.按照索引查找
//2.按照元素的具体值查找
//3.判断是否包含某一个元素
排序:这也是数据库提供的方法,在集合或高级数据结构中也适用;
集合的属性:如数据结构的长度、是否为空
用一张图汇总java中的集合类
再用一个表格进行一次汇总:
集合类使用的demo示例
其实记忆是很困难的,我们需要一些demo把一些关键的要点列举出来,从而可以在一个文章中多次复习。
旧的数据结构-Vector
旧的能够支持动态增长的数,https://www.runoob.com/java/java-vector-class.html
只想强调一下常用的几个方法即可:size(),get(),add(),remove(),clear(),set(i,o),contains(),indexof(),toArray()
新版本的vector实现了List接口,继承了AbstractList类。
@Test
public void testVector(){
Vector<String> vector = new Vector<String>();
vector.add("lujuan");
vector.add(0, "luchan");
System.out.println("0: "+vector.get(0));//luchan
vector.add("luhang");
System.out.println("last: "+vector.lastElement());//luhang
System.out.println("first: "+vector.firstElement());//luchan
System.out.println("middle: "+vector.elementAt((vector.size()-1)/2));//lujuan
vector.set(0,"luchanluchan");
vector.setElementAt("lujuanlujuan",(vector.size()-1)/2);
vector.remove(vector.size()-1);
System.out.println("first: "+vector.firstElement());//luchan
System.out.println("last: "+vector.elementAt((vector.size()-1)/2));//lujuan
}
旧的数据结构-Stack
是Vector的子类,除了Vector中定义的方法外,还额外增加了一些属于栈属性的方法。这个结构体希望大家能尽量熟悉的掌握,在刷算法题目的时候必不可少的数据结构
@Test
public void StackVector(){
Stack<Integer> stack = new Stack<Integer>();//只能用包装类
boolean empty = stack.empty();//判断栈是否为空,为空返回true
if(empty){
for(int i=0; i< 5;i++)
stack.push(i);//将元素放入栈中
}
while(!stack.empty()) {
System.out.println(stack.peek());//获得顶部元素
stack.pop();//移除顶部元素
}
}
旧的数据结构-Hashtable
基本上有了HashMap之后,这个应该是使用频次非常少的数据结构。Java 2 重构的Hashtable实现了Map接口,因此,Hashtable现在集成到了集合框架中。它和HashMap类很相似,但是它支持同步。
像HashMap一样,Hashtable在哈希表中存储键/值对。当使用一个哈希表,要指定用作键的对象,以及要链接到该键的值。
public class HashTableUsing {
@Test
public void testHashtable(){
Hashtable<String, Integer> hashtable = new Hashtable<String, Integer>();
System.out.println("size of hashtable: "+hashtable.size());
hashtable.put("lujuan", 1995);//存放key、value
hashtable.put("luchan",1992);//存放key、value
if(hashtable.containsKey("lujuan"))//判断是否又key值日
System.out.println(hashtable.get("lujuan"));//获取相应的value值
if(hashtable.contains(1995)){
System.out.println(1995);
}
Enumeration<Integer> testValue = hashtable.elements();//对所有元素进行迭代
while(testValue.hasMoreElements())System.out.println(testValue.nextElement());
Enumeration<String> testKey = hashtable.keys();
while(testKey.hasMoreElements()) System.out.println(testKey.nextElement());
hashtable.remove("lujuan");
hashtable.get("lujuan");
}
}
旧的数据结构-Properties类
这个是做测试框架中的参数配置化的过程中我们经常使用的一个类,主要是从配置文件中进行相应配置参数的解析,所以大家还是又必要学习一些这个类型。
参考学习文档:https://www.cnblogs.com/***1/p/5462151.html
需要load函数从Reader中读取,然后store函数,存储在文件中。
getProperty setProperty 是两个关键函数
package keyPoint;
import org.testng.annotations.Test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Set;
public class HashTableUsing {
@Test
public void testPropertiesWrite() throws Exception{
Properties properties = new Properties();
properties.setProperty("lujuan", "1995");
properties.setProperty("luchan","1992");
FileOutputStream fileWriter = new FileOutputStream("jiapu.properties");//需要使用OutputStream 来存储
properties.store(fileWriter,null);
fileWriter.close();
}
@Test
public void testPropertiesRead() throws Exception{
Properties properties = new Properties();
FileInputStream fileInputStream = new FileInputStream("jiapu.properties");//需要使用InputStream 来读取
properties.load(fileInputStream);
fileInputStream.close();
Enumeration<?> keys = properties.keys();
while(keys.hasMoreElements()){
String key = (String)keys.nextElement();
System.out.println(key+": "+properties.getProperty(key));
properties.setProperty(key, "1978");
}
FileOutputStream fileOutputStream = new FileOutputStream("jiapu.properties");
properties.store(fileOutputStream,null);
fileOutputStream.close();
}
}
旧的数据结构-Enumeration接口
至今为止没有怎么用过,可能主要是用在map类数据结构的迭代访问中。Enumeration是一个接口,作用类似于迭代器,接口中定义了两个方法hasMoreElement和nextElement,这个接口主要适用于旧的数据结构如Vector、Properties,以及其他的一个API上。
import java.util.Enumeration;
import java.util.Vector;
public class EnumerationUsing {
@Test
public void test(){
Vector<String> vector = new Vector<String>(5);
vector.add("1");
vector.add("2");
Enumeration<String> enumeration =null;
enumeration = vector.elements();//elements中重写可接口中定义的Enumeration两个方法
while(enumeration.hasMoreElements()){
System.out.println(enumeration.nextElement());
}
}
}
旧的数据结构-BitSet
这也是一个不怎么用的数据结构。
BitSet的参考文章:https://www.cnblogs.com/xujian2014/p/5491286.html 写的挺好的。
import java.util.BitSet;
public class BitSetUsing {
@Test
public void test(){
BitSet bitSet1 = new BitSet(16);//初始长度为8,每一位都为0
BitSet bitSet2 = new BitSet();//无初始化的长度,内容可动态的增加
for(int i = 0; i < 16;i++){
if(i%2 == 0)bitSet1.set(i);
}
for(int i = 0; i < 16;i++){
bitSet2.set(i);
}
System.out.println(bitSet1);//toString只返回为true的索引值,{0, 2, 4, 6, 8, 10, 12, 14}
System.out.println(bitSet2);
bitSet2.and(bitSet1); //and操作会改变bitSet2中的值
System.out.println(bitSet2);
bitSet2.or(bitSet1);//或操作
System.out.println(bitSet2);
bitSet2.xor(bitSet1);//yi或操作
System.out.println(bitSet2);//bitSet2全部为false
bitSet2.set(0,16);//没有办法获取这个set中有多少位,16位全部设置为true
bitSet2.set(0,1,false);//设置0为false
bitSet2.set(0,true);//设置0为true
bitSet2.clear(0);//设置0为fasle
bitSet2.clear();//设置全部为fasle
bitSet2.clear(0,2);//设置0,1为fasle
bitSet2.isEmpty();//如果全部为false,则返回true
bitSet2.set(0,16);
System.out.println(bitSet2);
bitSet2.andNot(bitSet1);//如果全部为false,则返回true将bitSet1中设置为true的位置对应的值置为false
System.out.println(bitSet2);
System.out.println("length of bitSet1: "+bitSet1.length());//length是最高为true的索引的大小
System.out.println("size of bitSet1: "+bitSet1.size());//实际占用的空间存储是大小,为64的整数倍
}
}
集合类的公共父亲接口-Collection
我们知道父接口中有那些方法,能够帮助我们更好的进行记忆。
其实观察下来就是我们上面所列举的增删改查四种类型。
int size(); boolean isEmpty(); Object[] toArray(); <T> T[] toArray(T[] a); Iterator<E> iterator(); boolean add(E e); boolean addAll(Collection<? extends E> c); boolean remove(Object o); boolean removeAll(Collection<?> c); void clear(); boolean retainAll(Collection<?> c); boolean contains(Object o); boolean containsAll(Collection<?> c); boolean equals(Object o); int hashCode() //其他
集合类的迭代器iterator
java中的迭代器有两种:
Iterator<Student> iterator = list.iterator();//单向迭代器
ListIterator<Student> listIterator = list.listIterator();//双向迭代器
//单向迭代器的使用方法,主要是hasNext和next函数
iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
两者的区别和详细比较:https://www.cnblogs.com/a842297171/p/5379130.html
只有list结构才能产生listIterator这样的迭代器。
集合类-list
Java中的List类型有ArrayList和LinkedList
List接口中定义的方法有
int size();
boolean isEmpty();
boolean contains(Object o);
boolean containsAll(Collection<?> c);
Iterator<E> iterator();
Object[] toArray();
boolean add(E e)
void add(int index, E element);
boolean addAll(Collection<? extends E> c);
boolean addAll(int index, Collection<? extends E> c);
boolean remove(Object o);
boolean removeAll(Collection<?> c);
int indexOf(Object o);
int lastIndexOf(Object o);
void clear();
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
ArrayList
public class ListUsing {
class Student implements Comparable<Student>{
public String name;
public int grade;
public Student(String name, int grade){
this.name = name;
this.grade = grade;
}
@Override
public String toString() {
return "name: "+ name +" grade: "+grade;
}
public int compareTo(Student o) {
if(this.grade<o.grade)return -1;
else{
if(this.grade>o.grade)
return 1;
else
return 0;
}
}
}
class ComparatorOfStudent implements Comparator<Student>{
public int compare(Student o1, Student o2) {
if(o1.grade > o2.grade)
return -1;
else{
if(o1.grade < o2.grade)
return 1;
else
return 0;
}
}
}
@Test
public void testArrayList(){
List<Student> list = new ArrayList<Student>();
Student student1 = new Student("1",1);
list.add(student1);
int key = list.indexOf(student1);
Student student2 = new Student("2", 2);
list.set(key,student2);
System.out.println(list.get(0).name);
list.remove(student2);
list.size();
list.isEmpty();
list.add(student1);
list.add(student2);
System.out.println("foreach遍历");
for (Student s:list) {
System.out.println(s.toString());
}
Iterator<Student> iterator = list.iterator();
ListIterator<Student> listIterator = list.listIterator();
System.out.println("迭代器遍历");
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//从大到小排列
System.out.println("从大到小排列");
ComparatorOfStudent comparatorOfStudent = new ComparatorOfStudent();
Collections.sort(list, comparatorOfStudent);//1.8中更推荐的是使用Collections中提供的算法。
iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
//从小到大排列
System.out.println("从小到大排列");
Collections.sort(list);//1.8中更推荐的是使用Collections中提供的算法。
iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println(list.contains(student2));//contains方法
//清除list
list.clear();
System.out.println(list.size());
}
}
LinkedList
//ArrayList的上述操作都能够使用LinkedList实现,只不过两者在不同场景下可能性能不同而已。 //ArrayList更适合用于随机访问的场所 //LinkedList更适合频繁增加和删除的场所。
集合类-set
三种Set集合的区别:https://blog.csdn.net/firearrow66/article/details/78858118
set接口定义的方法:
int size(); boolean isEmpty(); Object[] toArray(); <T> T[] toArray(T[] a); Iterator<E> iterator(); boolean add(E e); boolean addAll(Collection<? extends E> c); boolean remove(Object o); boolean removeAll(Collection<?> c); void clear(); boolean retainAll(Collection<?> c); boolean contains(Object o); boolean containsAll(Collection<?> c); boolean equals(Object o); //其他的
HashSet
HashSet底层是用HashMap实现.我们来看一个简单的demo:
|
|
控制台输出 |
在hashset中我们需要注意,如果不重写类的hashCode和equal方法(两个方法均需要重写)那么,默认会把元素的引用本身来辨别元素是否相同,如上所示,虽然两个元素值一模一样,但是还是可以添加到set中。我们进行如下的重写,可以看到判断元素相同了之后,add就没有办法添加了。
|
|
控制台输出 |
HashSet添加的顺序与迭代显示的结果顺序并不一致,如果要保持一致,可以使用LinkedHashSet来实现,LinkedHashSet会按照元素投放的顺序进行遍历。下面是代码的demo:
import org.testng.annotations.Test;
import java.util.HashSet;
import java.util.Iterator;
public class SetUsing {
class HashSetDemo{
public String key;
public int value;
public HashSetDemo(String key, int value){
this.key = key;
this.value = value;
}
@Override
public String toString() {
return "key: "+this.key+" value: "+this.value;
}
@Override
public int hashCode() {
return this.key.hashCode();
}
@Override
public boolean equals(Object obj) {
if(this.key.equals(((HashSetDemo)obj).key))
return true;
else
return false;
}
}
@Test
public void testHashSet(){
HashSet<HashSetDemo> set1 = new Hash
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
如果你在纠结做开发还是测试开发 如果你想知道测试开发到底做什么 如果你想提前避开一些本可以避开的坑 那么本专栏内容一定会帮助到你 专栏中不会有场面话 不会故弄玄虚 不会美化或丑化任何职业 就简单实实在在分享行业现状以及从业感受和经历 请相信一定是值得你阅读的专栏 如果你有任何其他问题 在学校里面找不到人问,也可以通过公众号找到我,欢迎骚扰 ~ 购买专栏后=专栏+简历Review+面试辅导
神州信息成长空间 29人发布
查看14道真题和解析