257 成长值

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

数据库、编程语言
个人勋章
TA还没获得勋章~
成长雷达
140
117
0
0
0

个人资料

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

数据库、编程语言

达成规则

发布时间 2021/09/06 09:50:21 最后回复 大卡 2021/11/03 21:04:04 版块 社区活动
7078 134 0
他的回复:
hw63088532 Java集合操作实战 笔记打卡java是一门面向对象的语言,Java提供集合就是为了方便我们去操作多个对象的。问:数组也可以存储多个数据,可以是基本数据类型,也可以是引用数据类型,为什么还需要集合呢?答:这个问题的关键点是:Java中的数组的长度一旦创建就不可变,而集合是可以动态扩展容量的,集合还提供了很多的API,能满足更多的需求!但是需要注意的是:数组中既可以存储基本数据类型,也可以存储引用数据类型,但是一个数组的类型在创建的时候就确定了;而集合只能存储引用数据类型(即使存进去的是基本数据类型,也会被自动装箱成引用数据类型),而且在不加泛型时,存储的数据可以是不同类型的,Object的子类即可Java集合框架可以分为两大支线:Collection和Map集合。Collection和Map是没有任何直接关系的,只是存在一些间接关系Collection 是单列集合;Map是双列集合(元素是以键值对方式存在的)CollectionCollection集合框架图Collection有三大子接口:List、Queue、Set,学习的重点是:List和SetList中的元素:有序可重复(可通过下标访问,允许重复值,允许多个null值);Set中的元素:无序不可重复List实现List集合的实现类主要有:LinkedList、ArrayList、VectorList接口继承自Collection,除了Collection中的方法,还有自己特有的方法ArrayListArrayList底层是Object[] 类型的数组,当添加第一个元素的时候,容量初始化为10,可以实现动态扩容,当容量不足时,底层会增加50%的容量但是注意:建议给定一个预估计的初始化容量,减少数组的扩容次数,这是ArrayList集合比较重要的优化策略ArrayList常用方法:Collection集合中元素的遍历接口Coolection继承了Iterable这个接口,接口Iterable中有个方法itrerator(),也被继承到了子接口上了,子接口只要去调用这个方法,就会产生这个集合所依赖的迭代器对象it,迭代器对象中有三个方法可以用来对所有的Collection集合中的元素进行迭代以ArrayList集合为例Collection c = new ArrayList(); //创建集合对象,并向集合中添加元素 c.add("abc"); c.add("def"); c.add(100); c.add(new Object()); Iterator it = c.iterator(); //通过集合对象中的iterator()方法获取迭代器对象it while(it.hasNext()) { //判断是否还有元素可迭代 System.out.println(it.hasNext()+"->"+it.next()); //输出迭代元素 }需要注意的是:如果集合发生了变化(调用集合的remove()、add()方法),迭代器就需要更新,如果集合发生变化,迭代器不更新就会抛出异常 java.util.ConcurrentModificationException,但是如果使用迭代器的remove()方法来删除元素的话,集合中对应的元素和迭代器中对应的元素都会同步更新,不会抛出异常!List集合遍历除了使用迭代方式之外,还可以使用for循环和增强for循环ArrayList要点:有序可重复,不是线程安全的,遍历快,添加删除慢LinkedListLinkedList与ArrayList一样实现List接口,只是ArrayList是List接口的大小可变数组的实现,LinkedList是List接口链表的实现。基于链表实现的方式使得LinkedList在插入和删除时更优于ArrayList,而随机访问则比ArrayList逊色些。通过对LinkedList的操作可以实现队列或栈的功能!LinkedList同时实现了List接口和Deque接口,也就是说它既可以看做为一个顺序容器,又可以看做一个队列Queue,同时又可以看做一个栈Stack。当你需要使用栈或者队列的时候,首先应该考虑的就是LinkedList。因为Java官方已经不建议使用Stack类,推荐使用LinkedListVectorVector是线程安全的动态数组,效率比较低,使用较少。Vector的底层也是一个数组,初始容量是10,ArrayList在底层数组不够⽤时在原来的基础上扩展0.5倍,Vector是扩展1倍。List总结:查询多⽤ArrayList,增删多⽤LinkedListSetSet接口是一种不包含重复元素的Collection,它维持自己的内部排序,所以随机访问没有任何意义。和List一样,允许null,但是只能有一个。由于Set接口的特殊性,所有传入Set集合的元素都必须不同。Set接口主要有两个实现类:HashSet和TreeSetHashSetHashSet堪称查询速度最快的集合,因为其内部是以hashcode()来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。TreeSetTreeSet集合存储元素的特点:无序不可重复的,但是存储的元素可以按照大小顺序自动排序,也就是说TreeSet集合可以对元素进行排序,并去重!注意:如果是自定义的类对象要放进Set集合中,一般要对继承自Object的hashCode()和equals()方法进行重写,以此来正确的判断元素是否重复MapMap集合中元素的特点:将键映射到值的对象,元素是成对出现的。一个映射不能包含重复的键,每个键最多只能映射到一个值,是单向的一对一关系。Map集合中常用方法:Map集合中的元素的遍历:方式一:通过Map.Entry来获取key和value通过Map.Entry(String,Integer)获取,然后使用entry.getKey()获取键值,通过entry.getValue()获取到value方式二:通过key集合获取value通过Map的keySet()获取key的Set集合,再通过 遍历key来遍历valueHashMapHashMap 以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的。键最多允许一个null,值可以多个为null非线程安全HashtableHashTable 也是以哈希表数据结构实现的,解决冲突时与HashMap也一样也是采用了散列链表的形式键和值都不能为null线程安全Collections工具类StreamJava8API添加了一个新的抽象类Stream,Stream使用一种类似于SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高阶抽象。Stream不是集合元素,也不是数据结构,也不保存数据,它是有关算法和计算的,它更像一个高阶版本的Iterator,但只能遍历一次,就好像一江春水向东流,一去不复返。Stream操作的三个步骤当我们使用一个流的时候,通常包括三个基本步骤:获取一个数据源source数据转换执行操作获取想要的结果
发布时间 2021/09/06 09:50:21 最后回复 大卡 2021/11/03 21:04:04 版块 社区活动
7078 134 0
发布时间 2021/09/06 09:50:21 最后回复 大卡 2021/11/03 21:04:04 版块 社区活动
7078 134 0
他的回复:
hw63088532 Java常用类实战 笔记一、字符串类String类在java中使用双引号括起来的都是String对象,String对象一旦创建就不可变。因为String类中,存放字符的是一个final修饰的Byte[]类型的数组,数组一旦被创建,长度就不可变,final修饰的引用一旦指向某个对象之后,就不能再指向新的对象。创建String类型字符串的两种方式:方式一:String s1 = "abc" 栈内存中的局部变量s1直接指向方法区常量池中的字符串“abc”方式二:String s2 = new String("abc")栈内存中的局部变量s2指向堆内存中的new的String对象,String对象那个中保存了方法区中“abc”的地址String类字符串的比较如果两个字符串用==直接进行比较,比较的是两个字符串对象的地址。要想比较两个字符串是否一样,应该用equals()方法进行比较,String类重写了equals()方法,比较的是两个字符串的内容是否相等字符串常用APIequals()比较两个字符串是否相等;length()返回字符串的长度,tocharArray()将字符串转换为字符数组indexOf() 返回第一次出现某个字符串的位置.......StringBuffer和StringBuilderStringBuffer和StringBuilder都是可变的字符序列,区别在于StringBuffer是线程安全的,效率低,而StringBuilder不是线程安全的,效率高。二、Java其他常用类 System类System类 :无法创建该类对象,因为其构造方法是private修饰的。内部的成员变量和方法均是static的,直接通过类名调用属性:System.in 输入流   System.out 输出流   System.err 标准错误输出流方法:System.arraycopy(Object src,int srcPos,Object dest,int destPos,int length)  将一个数组元素快速拷贝到另一个数组中,需要注意的是目标数组必须要有足够的空间来存放要拷贝的元素System.currentTimeMillis();获取当前的系统时间,单位是ms。这个毫秒其实就是自1970年1月1日0时起的毫秒数System.getProperty("xxx"); 读取JVM中的系统属性,比如“java.version”“os.name”等CharSequence接口CharSequence是一个描述字符串结构的接口,有三个常用的子类:String,StringBuffer,StringBuilder在CharSequence中有方法:charAt(int index);length​(),subSequence​(int start, int end)Runtime类Runtime类代表的是运行时环境,每个Java应用程序都有一个Runtime类实例对象,使应用程序能够与其运行的环境相连接。Cleaner类Cleaner类负责清理对象,替代了Object类中的finalize()方法Math类Math类中封装的是和数学运算相关的操作Random类Random类用于产生随机数Random random = new Random(); int num = random.nextInt(n); //返回一个[0,n)之间的整数UUID类UUID类可以产生通用唯一识别码深度克隆和浅度克隆克隆就是复制一个一摸一样的对象出来,分为深度克隆和浅度克隆一个对象要实现克隆,首先要实现Cloneable接口并重写clone()接口深度克隆:在复制对象本身的同时也复制了对象中引用指向的对象,即复制后的对象和复制前的对象是独立的,修改其中一个不会影响另一个浅度克隆:在复制对象时仅仅复制对象本身,包括基本属性和不可变属性,但该对象的引用指向的对象不会被复制,即复制之前的对象和复制之后的对象中的同类型同名引用属性指向的是同一个对象,无论是修改复制之前对象的引用属性指向的对象还是复制之后的对象的引用,修改的都是同一个
发布时间 2021/09/06 09:50:21 最后回复 大卡 2021/11/03 21:04:04 版块 社区活动
7078 134 0
他的回复:
hw63088532  Java多线程实战 笔记第一章 创建线程一、什么是进程,线程?进程可以理解为一个应用程序的执行过程,应用程序一旦执行,就是一个进程。进程是资源分配的基本单位。不同进程之间的地址空间是独立的,进程之间的资源也是独立的,无法共享。线程是进程中的一个执行单元,进程是任务调度的基本单位,一个进程中可以启动多个线程。同一进程中的多个线程共享本进程的地址空间和资源二、如何创建线程?第一种方式:继承Thread类继承Thread并重写其run()方法,run()方法中定义线程需要执行的任务。用创建的子类对象去调用start()方法来启动线程,即可自动执行线程中重写的run()方法public class Demo { public static void main(String[] args) { MyThread t1 = new MyThread(); //创建线程t1对象 MyThread t2 = new MyThread(); //创建线程t2对象 t1.start(); //启动线程1 t2.start(); //启动线层2 } } class MyThread extends Thread{ //重写run public void run(){ //线程执行体 } }特点:通过继承Thread类实现的线程类,多个线程之间无法共享线程类的实例变量。注意:在主线程main中创建MyThread类的分支线程对象,然后用分支线程对象去调用start()方法来启动线程,线程启动成功后,等待CPU调度,拿到CPU时间片之后就开始运行run()方法,若CPU中的时间片用完之后,就又回到就绪状态继续等待CPU调度,等待下一次继续执行run().....如果用线程对象直接调用run()方法的话,并不会启动一个线程,此时跟一个普通对象调用方法没有任何区别,还是运行在主线程main中第二种方式:实现Runnable接口1、实现Runnable接口,重写run()方法public class MyRunnable implements Runnable{ //override public void run(){ //线程执行体 } }2、启动线程new Thread(new MyRunnable()).start();还可以采用匿名内部类的方式new Thread(){ //override public void run(){ //执行体 } }.start();Thread类和Runnable接口的区别:Runnable是父类,Thread是子类;Java只支持单继承,实现Runnable接口可以避免实现Thread类的单继承的局限,可以更好的体现共享的概念三、线程的优先级Java线程优先级的范围是1~10,默认优先级是5,主线程main的优先级也是5注意:线程的优先级高只能说获取CPU资源的概率较大,但是并不是说优先级的低的就没有机会执行,线程的优先级是无法保证线程的执行次序的第二章 线程生命周期和状态在一个线程的生命周期中,有五种状态:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocking)和死亡(Dead)新建状态:当使用new关键字创建了一个线程对象之后,该线程就处于新建状态了,此时JVM会为其分配内存,并初始化其成员变量的值就绪状态:当新建状态的线程对象调用了start()方法之后,该线程就处于就绪状态了,JVM会为其分配调用栈,程序计数器,等待CPU的调度运行状态:如果处于就绪状态的线程抢到了CPU的时间片,就会开始执行run()方法中的线程执行体,此时的线程就处于运行状态了阻塞状态:当处于运行状态的线程失去所占用的CPU资源后,便进入阻塞状态死亡状态:run()方法执行结束标志者线程进入死亡状态,或者线程被提前终止或出现异常导致线程死亡当线程启动以后,CPU需要在多条线程之间切换,于是线程状态也会多次在运行阻塞之间切换Thread.sleep(long millis)Thread.sleep(long millis)可以让线程睡眠指定的时间,线程在休眠的时候,会将CUP的资源交给其他线程,当到了指定的时间之后,线程会苏醒,重写进入就绪状态等待CPU调度。在哪个线程中调用sleep()方法,哪个线程就休眠!Thread.yield()当一个线程调用Thread.yield()方法之后,这个线程就会由当前的“运行状态”进入到“就绪状态”,从而让其他具有相同优先级的等待线程获得执行权,但是并不能保证其他具有相同优先权的线程一定能获得执行权。join()当一个线程对象调用join()方法之后,就会等待该线程执行完毕之后别的线程才执行别的线程,它是一种线程栈之间的协调等待setDaemon(true)当一个线程对象调用setDaemon()方法时,可以将该线程标记为守护线程(比如垃圾回收线程),且必须在启动线程前调用。当正在运行的线程都是守护线程时,JVM会自动退出!线程的中断和死亡线程会以如下三种方式结束1)run()或call()方法执行完成,线程正常结束2)线程抛出一个未捕获Exception或Error3)直接调用该线程stop方法结束该线程-但一般不推荐使用!第三章 线程同步和安全一、线程并发的不安全问题Java中有三大变量:实例变量,静态变量,局部变量。其中局部变量因为在线程栈中,为线程私有,不会有线程安全问题,但是在方法区的静态变量和在堆中的实例变量如果被多个线程共享,且并发修改的话,就会存在线程安全问题!二、线程同步机制在Java中,每一个对象都拥有一个锁标记,多个线程同时访问某个对象时,只有拥有该对象锁的线程才能访问,如果给多个线程要访问的共享资源用synchronized关键字加上锁的话,只有拿到锁的线程才可以对贡献资源进行访问,没有拿到锁的资源需要等待释放锁后才能访问,这样就可以实现线程串行访问共享资源,实现线程的同步机制。同步代码块synchronized(objLock){ //同步代码块 }被synchronized修饰的代码任何线程在访问之前必须先取得锁对象objLock,在该锁未释放之前,其他线程是不能拿到的。当该线程执行完毕里面的同步代码块之后,就会释放锁,此时排队等待的线程才可以拿到该锁,执行同步代码块,这样就保证了线程同步。
发布时间 2021/09/06 09:50:21 最后回复 大卡 2021/11/03 21:04:04 版块 社区活动
7078 134 0
他的回复:
hw63088532 Java数组 笔记一、什么是数组,如何定义数组?数组是一种数据类型,用来存储具有相同类型的一组数据问:如何声明一个一维数组?Java中数组的声明有两种方式:第一种:数组类型[] 数组名  比如:int[] arr;第二种:数组类型 数组名[] 比如: int arr[]以上两种声明方式的区别就在于[]的位置,前一种是Java常用方式,后一种是c++风格,但在Java中是合法的问:如何初始化一个一维数组?有两种方式:一种是静态初始化,一种是动态初始化方式一:静态初始化数组类型[] 数组名 = new 数组类型[]{元素1取值,元素2取值....} int[] arr = new int[]{3,45,60}在声明数组的同时,用{}的方式对数组直接赋值。对于静态初始化,Java提供了简写的格式数组类型[] 数组名 = {元素1取值,元素2取值....}; int[] array = {100,2100,300,55};方式二:动态初始化数组类型[] 数组名 = new 数组类型[数组长度] int[] array = new int[5]; //这里5表示的是数组元素的个数, 表示初始化一个长度为5的整型数组,每个元素的默认值是0动态初始化就是初始化时在方括号中指明数组的长度,由系统为数组分配初始化默认值,不同数据类型的默认值是不同的在创建数组的时候,如果确定数组中的具体元素,可以采用静态初始化;如果不确定数组中存储哪些数据,可以采用动态初始化方式,预先分配内存空间,后期再赋值二、一维数组元素的访问和遍历数组中的元素是按索引编号的,从0开始,逐次加1,arr.length-1结束,是连续。直接通过数组名[索引] 即可访问,数组中的每个元素其实都是一个变量,也可以重新赋值。注意:访问数组元素过程中,如果索引的值超出了数组的界限[0,arr.length-1],就会抛出IndexOutOfBoundsException异常遍历数组就是挨个获取数组中的每个元素,最常用的是使用for循环,如下// 使用静态初始化的方式声明一个int类型的数组 int[] a1 = {1,100,10,20,55,689}; // 从第一个元素遍历到最后一个元素 for(int i=0;i/ 从最后一个元素遍历到第一个元素 for(int i=a1.length-1;i>=0;i--){ System.out.println(a1[i]); }三、二维数组二维数组就是数组中的数组,也就是数组中的每一个元素也是一个一维数组数据类型[][] 数组名 = new 数组类型[外层数组长度][内层数组长度]外层数组长度表示的是整个数组的长度,通过数组名.length获取,内层数组长度表示数组中每个元素的数组长度二维数组的遍历for(int i=0;i/外层数组长度 for(int j=0;j/内层数组长度 System.out.print(score[i][j]+" "); } System.out.println(); }四、数组相关算法1)排序数组排序就是值将数组元素按照从小到大或从大到小的顺序排序,常见排序算法有:插入排序,冒泡排序,快速排序等,一般是通过数组中元素的交换次数来衡量排序算法的优劣以冒泡排序为例:public class Demo { public static void main(String[] args) { int[] arr = {89,50,84,57,21}; for(int i=0;iarr[j+1]) { temp = arr[j+1]; arr[j+1] = arr[j]; arr[j] = temp; } } } for(int i=0;i/假设数组中的第一个元素为最大值 for(int i=1;imax) { max=arr[i]; } } System.out.println(max); //101求最小值算法:定义一个变量存放最小值,假设数组中第一个元素是该变量的初始值,该变量跟数组中其他值挨个比较,如果遇到比该值更小的就重新赋值为这个较小者,比较完所有元素之后,该变量最后的值就是数组中的最小值3)数组的过滤重复算法:去掉数组中重复的数据,给每个元素一个标记,每个元素跟数组中的其他元素进行比较,如果完全相同就改变原有标记,将没有改变标记的元素重新放入一个新的数组,并统计其个数,最终将新数组的数据复制到另一个新的数组中,就是过来的数组注意:因为事先是不知道不重复的元素的个数的,申请的tempArr数组的长度和原数组长度是一样长的,如果直接输出tempArr的话,会发现数组的后几位可能是默认值0所以,在统计出不重复的元素的个数之后,再用System.arraycopy()方法将数组中不重复的值复制到一个新的数组中 //再创建一个数组,用来存放过滤后的数组 int[] newArr = new int[t]; //将tempArr中非零的元素复制到newArr中(假设原数组中没有0) System.arraycopy(tempArr,0,newArr,0,t); //输出过滤后的数组 for(int i=0;i/12 67 34 45 五、Arrays工具类的使用JAVA提供了一个数组工具类java.util.Arrays,基本上常见的数组操作,这个类都提供了静态方法可供直接调用