java基础知识7

1.

进程:一个正在运行的程序拥有该程序运行的所有资源,包括资源的分配和任务的调度。

线程:在进程中负责具体代码的执行,一个进程至少有一个线程

单线程:在整个程序中只有一个线程,这个线程为主线程

多线程:整个程序不止一个线程,除了主线程其它为子线程

并发:多个任务独立执行,一起执行

同步:同一时刻只能执行一个任务,该任务执行完成之后才能执行下一个任务

异步:一个线程中多个任务同时执行,一起执行

多线程:操作系统同时执行多个任务
创建线程的方式:

1)继承Thread,重写run()方法

有开辟线程的能力,资源共享方面不是很方便。

2)实现runable接口,实现该接口的run()方法

没有开辟线程的能力,要将创建的对象交给指定线程来运行

线程池:

帮助我们管理线程,我们只需要将需要执行的任务交给线程池。

线程池会根据任务的个数,执行时长,将不同的任务交给线程池中的线程来执行。

线程死锁:

多个线程因为竞争资源而造成相互等待,若无外力作用这些进程都将无法向

防止线程死锁:

        1)加锁顺序

        2)加锁时限

        3)加锁检验

线程锁:

当多个数据访问资源时,为了数据安全,保证当一个线程访问资源时,

其它线程不能访问。等上一个线程访问完成之后才能访问。

同步锁:

synchronized(对象){
    //同步代码块: 同一个对象锁下的所有线程,某个时间段内只能有一个线程在执行该代码块
     }

在同步代码块内:

wait():当前线程停止运行,被同一个线程锁的其它线程唤醒之后才能接着运行

wait(时长毫秒):当前线程停止运行,当超过指定时长还没有被唤醒,就不等其它线程唤醒了,接着执行。

notify(): 唤醒同一个同步锁中某一个wait()锁

notifyAll(): 唤醒同一个同步锁中所有wait()线程

线程的生命周期:

        创建(new)---就绪(start)---运行状态(等待CPU调用run方法,如果线程在运行时发生阻塞,

进入阻塞状态,之后又返回就绪状态,等待CPU的再次调用)---结束状态(run方法执行完成)

run和start方法的区别:

          start:重新开启了一个线程,不必等待其它线程执行完成。

           run:只是调应了一个普通方法,没有开启线程,程序还会按照顺序执行响应代码。

2.Hibernate为什么需要二级缓存?

   Mybatis如何开启二级缓存?

   Hibernate如何开开启二级缓存?

2.1>Hibernate为什么需要需要二级缓存:

一级缓存是session级别的缓存,它属于事物级别的缓存,由hibernate管理,一般无需进行干涉。

二级缓存是SessionFactory级别的缓存,它是进程范围或群集范围的缓存。可以进行配置和更改,

并且可以动态进行加载和卸载。当一些数据不常发生变化或者允许偶尔的并发的时候,

二级缓存可能更有效率,因为它的缓存时间更久,不会像一级缓存一样一旦session销毁就销毁。

2.2>Mybatis开启二级缓存:

       2.2.1>mybatis-config.xml

                cacheEnabled介绍:

                      允许值:对在此配置文件下的所有cache进行全局性开/关设置

                       默认值:true

       2.2.2>在mapper.xml中开启二级缓存,mapper.xml下的sql执行完成会存储到它的缓存区

            开启缓存后,第一次查询会执行sql,第二次及以后的查询都会在缓存中读取数据

        注意:开启缓存的弊端是数据没有实时性,当数据库中的数据一旦修改,查询的数据还是缓存中的数据没有实时性,对于某些需要实时性显示数据的接口我们可以设置useCache="false",设置该属性后,该接口每次查询出来都是去执行sql查询出实时性数据。

相关配置说明:

     ①.设置useCache=false可以禁用当前select语句的二级缓存,

    即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

总结:针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存。

         

    ②.清空缓存

总结:一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读。

         

注意:

(1)当为select语句时:

flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。

useCache默认为true,表示会将本条语句的结果进行二级缓存。

(2)当为insert、update、delete语句时:

           flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。

           useCache属性在该情况下没有。

        当为select语句的时候,如果没有去配置flushCache、useCache,那么默认是启用缓存的,

所以,如果有必要,那么就需要人工修改配置

         2.2.3>对应的pojo实现序列化(implements Serializable)

         2.2.4>mybatis自身实现二级缓存弊端在于只能作用于数据库,

            此时需要我们引用第三方库作为缓存库,这样缓存更具有扩展性

2.3>hibernate开启二级缓存

        开启二级缓存需要导入三个jar包,还有一个配置文件到资源根目录下

                

         ehcache.xml:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> 	
	<!-- 缓存数据要存放的磁盘地址 -->
	<diskStore path="java.io.tmpdir" /> 
	<!-- diskStore:指定数据在磁盘中的存储位置。 ? defaultCache:当借助CacheManager.add("demoCache")创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略 
		以下属性是必须的: ? maxElementsInMemory - 在内存中缓存的element的最大数目 ? maxElementsOnDisk 
		- 在磁盘上缓存的element的最大数目,若是0表示无穷大 ? eternal - 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断 
		? overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上 以下属性是可选的: ? timeToIdleSeconds 
		- 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大 
		? timeToLiveSeconds - 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大 diskSpoolBufferSizeMB 
		这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区. ? diskPersistent 
		- 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。 ? diskExpiryThreadIntervalSeconds 
		- 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作 ? memoryStoreEvictionPolicy 
		- 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出) -->
 
	<defaultCache maxElementsInMemory="1000"
		maxElementsOnDisk="10000000" eternal="false" overflowToDisk="false"
		timeToIdleSeconds="120" timeToLiveSeconds="120"
		diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU">
	</defaultCache>
 
	 <!-- 
		name: cache的名字,用来识别不同的cache,必须惟一。   
		maxElementsInMemory: 内存管理的缓存元素数量最大限值。   
		maxElementsOnDisk: 硬盘管理的缓存元素数量最大限值。默认值为0,就是没有限制。   
		eternal: 设定元素是否持久话。若设为true,则缓存元素不会过期。   
		overflowToDisk: 设定是否在内存填满的时候把数据转到磁盘上。
		timeToIdleSeconds: 设定元素在过期前空闲状态的时间,只对非持久性缓存对象有效。默认值为0,值为0意味着元素可以闲置至无限长时间。   
		timeToLiveSeconds: 设定元素从创建到过期的时间。其他与timeToIdleSeconds类似。   
		diskPersistent: 设定在虚拟机重启时是否进行磁盘存储,默认为false.(我的直觉,对于安全小型应用,宜设为true)。   
		diskExpiryThreadIntervalSeconds: 访问磁盘线程活动时间。   
		diskSpoolBufferSizeMB: 存入磁盘时的缓冲区大小,默认30MB,每个缓存都有自己的缓冲区。   
		memoryStoreEvictionPolicy: 元素逐出缓存规则。共有三种,Recently Used (LRU)最近最少使用,为默认。 First In First Out (FIFO),先进先出。Less Frequently Used(specified as LFU)最少使用  
	-->
	<cache name="userCache" maxElementsInMemory="3000" eternal="false"
		overflowToDisk="true" timeToIdleSeconds="3600" timeToLiveSeconds="3600"
		memoryStoreEvictionPolicy="LFU" />
 
</ehcache>

          hibernate.cfg.xml:

<!-- 二级缓存配置 -->
	   <!-- 默认是不使用二级缓存,设置使用二级缓存 -->
	  <property name="hibernate.cache.use_second_level_cache">true</property>	
	     
	 <!-- 开启查询缓存,如果不开启,每次查询完只存主键,开启后可以存其它字段,拿到一条完整的记录 -->
	  <property name="hibernate.cache.use_query_cache">true</property>
	  
	  <!-- 开启查询缓存(一般配合二级缓存使用,两个都设置为true)
	      如果没有开启二级缓存,只开启了查询缓存,此时缓存中只存储查询出来的数据的id
	      如果后续再查询相同的数据,根据缓存中的id分条查询数据
	   -->  
	  <!-- 配置谁来支撑 -->
	  <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
	  
	   <!-- 引入映射文件 -->
	    <mapping resource="com/zhou/model/ClassRoom.hbm.xml"/>
	    <mapping resource="com/zhou/model/Student.hbm.xml"/> 

        <!--类级别缓存-->
      <class-cache usage="read-write" class="net.seehope.hibernate.pojo.Customer" />
      <class-cache usage="read-write" class="net.seehope.hibernate.pojo.Orders" />
        <!--集合缓存-->
      <collection-cache usage="read-write"   collection="net.seehope.hibernate.pojo.Customer.Orders"
         
	  	  <!-- 设置使用二级缓存的对象并指定并发策略-->
	  <!-- <class-cache usage="read-only" class="com.zhou.model.ClassRoom"></class-cache> -->

                 注意:开启缓存要写在mapping映射下方   

                         里面的集合缓存意思是缓存orders的id还是需要把Orders这个类也进行缓存 

3.跨域?如何解决跨域问题?

跨域:前端页面与后台运行在不同的服务器上

解决跨域问题:使用cors

特点:前端代码和未处理跨域前一样,即普通的ajax请求,

          但服务器代码添加了一段解决跨域的代码

前端代码

服务器代码

cors高级使用:在springmvc中配置拦截器

创建跨域拦截器实现HandlerInterceptor接口,并实现其方法,在请求处理前设置头信息,并放行

在springmvc的配置文件中配置拦截器,注意拦截的是所有的文件

4. 拦截器,过滤器,监听器的启动顺序? 配置位置?

    spring监听器配置? 设置处理字符编码的过滤器?

    配置拦截器?过滤器和拦截器的区别?

启动顺序:

       监听器 > 过滤器 > 拦截器

     接到上级命令,要求对电话进去监听,过滤出恐怖分子,然后,拦截他们的恐怖袭击行动。

配置位置:

        监听器,过滤器一般配置在web.xml中。

        拦截器一般配置在springmvc.xml配置文件中

spring监听器的配置:在web.xml中

<!--spring监听器配置 -->
<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

 处理字符编码的过滤器:前端请求为post方式时,设置中文格式的过滤器,处理中文乱码格式

<filter>
  <filter-name>CharactorFilter</filter-name>    <!--过滤器名称 -->
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  <!--过滤器的完整类名 -->
  <init-param>   <!--初始化参数 -->
	<param-name>encoding</param-name>  <!--参数名称 -->
	<param-value>utf-8</param-value>   <!--参数值 -->
  </init-param>
  <init-param>
	<param-name>forceEncoding</param-name>
	<param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping> <!--过滤器映射 -->
    <filter-name>CharactorFilter</filter-name><!--过滤器名称 -->
	<url-pattern>/*</url-pattern><!--URL映射,给所有页面处理乱码 -->
</filter-mapping>

配置拦截器:在springmvc.xml中

<!-- 处理拦截器的配置 -->
<mvc:interceptors>
  <mvc:interceptor>
     <!--要被拦截的目录  -->
     <mvc:mapping path="/managerLogin"/>
     <!-- 配置拦截器 -->
     <bean class="com.yangsheng.inteceptor.LoginInterceptor"></bean>
  </mvc:interceptor>
</mvc:interceptors>

   LoginInterceptor.java

public class LoginInterceptor implements HandlerInterceptor {
     /**
	 * 调用handler之后执行
	 */
      @Override
      public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        		throws Exception {
        	// TODO Auto-generated method stub
        	HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        	
        	/**
    		 * 1.获得客户机信息
    		 */
    		String requestUrl = request.getRequestURL().toString();// 得到请求的URL地址
    		String requestUri = request.getRequestURI();// 得到请求的资源
    		String queryString = request.getQueryString();// 得到请求的URL地址中附带的参数
    		String remoteAddr = request.getRemoteAddr();// 得到来访者的IP地址
    		String remoteHost = request.getRemoteHost();
    		int remotePort = request.getRemotePort();
    		String remoteUser = request.getRemoteUser();
    		String method = request.getMethod();// 得到请求URL地址时使用的方法
    		String pathInfo = request.getPathInfo();
    		String localAddr = request.getLocalAddr();// 获取WEB服务器的IP地址
    		String localName = request.getLocalName();// 获取WEB服务器的主机名
    		String contextPath = request.getContextPath();
    		
    		System.out.println("请求的URL地址:" + requestUrl);
    		System.out.println("请求的资源:" + requestUri);
    		System.out.println("请求的URL地址中附带的参数:" + queryString);
    		System.out.println("来访者的IP地址:" + remoteAddr);
    		System.out.println("来访者的主机名:" + remoteHost);
		    System.out.println("使用的端口号:" + remotePort);
		    System.out.println("remoteUser:" + remoteUser);
    		System.out.println("请求使用的方法:" + method);
    		System.out.println("pathInfo:" + pathInfo);
    		System.out.println("localAddr:" + localAddr);
    		System.out.println("localName:" + localName);
    		System.out.println("contextPath:" + contextPath);
        }
     
     /**
	 * 调用handler过程中执行
	 */
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2, ModelAndView arg3)
			throws Exception {
	}
	
	/**
	 * 在调用handler之前调用
	 * true 不拦截;false 拦截
	 */
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,Object arg2) throws Exception {
		arg0.setCharacterEncoding("utf-8");
		//如果用户没有登录则禁止访问,跳转到登录页面
		if(arg0.getSession().getAttribute("user")==null){
			arg0.getRequestDispatcher("login.jsp").forward(arg0, arg1);
			return false;
		}
		   return true;
	}

  }

过滤器和拦截器的区别:

1)Filter需要在web.xml中配置,依赖于servlet.

2)  Interceptor需要在springmvc中配置,依赖于框架

3)Filter的执行顺序在Intercetor之前。

4) Interceptor是基于java的反射机制的,而过滤器是基于函数回调的

 5)从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类)     

 6) Interceptor只能对action请求起作用,而过滤器可以对所有的请求起作用。

5.Mybatis多表联查

5.1)一对多

     一方表
     多方表:多一个字段作为外键,此外键是和一方的主键关联
     mybatis一方的配置文件resultMap中<collection property="集合的属性名" ofType="集合元素的类型"></collection>
     多方的配置文件resultMap中<association property="一方的属性名" javaType="属性类型"></association>

5.2)多对多

    多方表1
    多方表2
    中间表 :其中一个字段为表1的外键,另一字段为表2的外键
    在各自的resultMap中<collection></collection>

5.3)一对一

    表1
    表2: 在表2中增加一个字段是表1的外键,并且加唯一约束
    在各自的resultMap中<association></association>

6.数组排序

6.1)冒泡排序

/*
 * 外层for循环代表循环次数
 * 内层for循环对数字进行排序
 */

	int[] sort(int[] array){
    	   if( array == null ){    //数组为空
    		   System.out.println("数组不能为null");
    		   return array;
    	   }
      if( array.length <= 1){  //数组的元素不大于1
    	      return array;
      }
    for(int i = 0; i < array.length-1; i++){
    	  for(int j = 0; j < array.length-1-i; j++){
    		  if(array[j] > array[j+1]){
    			  int temp = array[j];
    			  array[j] = array[j+1];
    			  array[j+1] = temp;
    		  }
    	  }
    }             
               return array;
       }   

6.2)自然排序

package java_排序和二分查找;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Text_自然排序1 {

	public static void main(String[] args) {
		
		   ArrayList<Girl> list = new ArrayList<>();
			list.add(new Girl(25, "周帅", 174, 100));
			list.add(new Girl(30, "张三", 178, 120));
			list.add(new Girl(22, "李四", 163, 90));
			list.add(new Girl(38, "毕燕", 165, 85));
  /*
   * sort括号里面使用匿名内部类,只要将if参数里面改动,
   * 就可以给4个随便哪个进行排序
   */
	 Collections.sort(  list, new Comparator<Girl>() {

		@Override
		public int compare(Girl o1, Girl o2) {
			if(o1.age > o2.age) {
				return 1;
			} else {
				return -1;
			}
			
		}
	}  );
	       for (Girl girl : list) {
			System.out.println(girl);
		}
	
	}
}
class Girl implements Comparable<Girl> {
      public  int age;
      public String name;
      public int height;
      public int score;     
	
    public Girl(int age, String name, int height, int score) {	
		this.age = age;
		this.name = name;
		this.height = height;
		this.score = score;
	}
      @Override
    public String toString() {
    	  String s1 = "name:" + name + " ";
    	  String s2 = "age:" + age + " ";
    	  String s3 = "height:" + height + " ";
    	  String s4 = "score:" + score  + " ";
     	return s1 + s2 + s3 + s4;
    }
	@Override
	public int compareTo(Girl o) {
		// TODO Auto-generated method stub
		return 0;
	}
	
}

6.3)快排

package java_排序和二分查找;

import java.util.Arrays;

public class Text_快排 {

	public static void main(String[] args) {
		int[] array = { 10,30,15,12,56,9};
		    sort(array, 0, array.length-1);
          System.out.println(Arrays.toString(array));
	}
	//快速排序
    public static void sort(int[] array, int begin, int end) {
    	   //当满足该条件,说明已经没有数字了或者只剩下一个数字了,没有必要再比较了
      	if (begin >= end) {
			  return;
		}
       //基准数
    	int key = array[begin];
    	//记录开始和结束位置
    	int start = begin;
    	 int over = end;
    	 /*
    	  * 从后面找到小的放到前面,
    	  * 从前面找到大的放到后面,
    	  * 当start 和 over 相遇,说明已经分区完成
    	  */
   while(start < over) {
    		 //从后面找到小的放到前面,当找到array[over] < key 小的停止
    		while(over > start && array[over] >= key) {
    			    over--;
    		 }
    		//将找到的比基准数(key)小的数字往前放
    		 array[start] = array[over];
    		//从前面开始,找到比基准数大的,往后放
    		while(over > start && array[start] <= key){
    			   start++;
    		}
    	 //找到前面比基准数大的,往后放
    		array[over] = array[start];
    	 }
    	 //将记录的基准数,放到相遇位置
    	    array[start] = key;
    	 //左区按照同样的原理,接着排序
    	    sort(array, begin, start-1);
    	  //右区
    	    sort(array, start+1, end);
    }
}

6.4)选择排序

package java_排序和二分查找;

import java.util.Arrays;

public class Text_选择排序 {

	public static void main(String[] args) {
	/*
	 * 选择排序:
	 *   内层循环记录最小值的下标,
	 *   将记录的最小值下标跟外层的i进行位置调换
	 */
		int[] array = { 50, 30, 20, 60, 15 };
		for(int i = 0; i < array.length; i++){
			   int index = i;  // index 记录最小值的下标
		for(int j = i+1; j < array.length; j++){
			if(array[index] > array[j]){
				index = j;
			}
		}
		 if( index != i ){
			   int temp = array[index];
			   array[index] = array[i];
			   array[i] = temp;
		 }			   
		}
	System.out.println(Arrays.toString(array));			
	}
}

6.5)冒泡和二分查找封装

package java_排序和二分查找;


public class Text_冒泡和二分查找封装 {
	
	int[] sort(int[] array) {
		if (array == null) { // 数组为空
			System.out.println("数组不能为null");
			return array;
		}
		if (array.length <= 1) { // 数组的元素不能小于1
			return array;
		}
		for (int i = 0; i < array.length; i++) {
			int index = i; // 记录最小值下标
			for (int j = i + 1; j < array.length; j++) {
				if (array[index] > array[i]) {
					index = j;
				}
			}
			if (index != i) {
				int temp = array[index];
				array[index] = array[i];
				array[i] = temp;
			}
		}
		return array;
	}

	int search(int[] a, int key) {
		int[] sc = this.sort(a);
		if (sc == null) {
			System.out.println("数组不能为null");
			return -1;
		}
		int index = -1;
		int left = 0;
		int right = sc.length - 1;
		int middle = (left + right) / 2;
		while (left <= right) {
			middle = (left + right) / 2;
			if (key == sc[middle]) {
				index = middle;
				break;
			} else if (key > sc[middle]) {
				left = middle + 1;
			} else {
				right = middle - 1;
			}
		}
		if (index == -1) {
			System.out.println("不存在");	
			   return -1;
		} else {		
			System.out.println("在数组a的第" + (index + 1) + "位");
			return index;
		}
	}
}



package java_排序和二分查找;

public class Text_封装 {

	public static void main(String[] args) {
	   
         Text_冒泡和二分查找封装  sc = new Text_冒泡和二分查找封装();
            int[] a = new int[]{ 20, 50, 60, 10, 100 };
                  sc.sort(a);
             for(int temp : a){
        	    System.out.print(temp + " ");
              }
	             System.out.println();
	     Text_冒泡和二分查找封装  sv = new Text_冒泡和二分查找封装();
	        sv.search( a, 50);
	}
}

6.6)插入排序

package java_排序和二分查找;

import java.util.Arrays;

public class Text_插入排序 {

	public static void main(String[] args) {
		/*
		  * 定义一个整形数组,里面有10个元素,
		  * 对数组进行升序排列
		  * 然后使用二分法查找找数组中是否有2这个元素	
		  */
		int[]array={10,8,9,50,101,102};
		/* 假设第一个元素为有序数据
		 * 无序的数据:有length-1个数字 
		 */
	for(int i=1;i<array.length;i++){
		/* i就是从无序的数据中拿出的数字下标
		 所以[0,i-1]是有序数据
		 用下标为i的和i-1比较,如果比i-1小再和i-2比较
		  直到某个数字比i下标的数字还小为止。
		 从找到的位置到i-1、集体往后移动一位数字,
		 为目前i下标数字留出位置*/
		//将要确定的数字先保存起来
		int temp=array[i];
		//记录最终数字的位置
		int index=0;
		//和有序数字进行比较,从大数到小数比较
		for(int j=i-1;j>=0;j--){
			//要确定位置的数字找比有序数据中比他还小的数字
			if(array[i]>array[j]){
				index=j+1;
				break;
			}
		}
	/*
	 * 挪位置 找到位置为 index 要确定的数字的位置i
	 * 从index到i-1统统往后挪一位
	 */
	for(int k = i-1; k >= index; k--){
		array[k+1] = array[k];
	}
	//将temp值插入到index的位置
	array[index] = temp;
	}
	System.out.println(Arrays.toString(array));	
	}
}

6.7)二分插入排序

package java_排序和二分查找;

import java.util.Arrays;

public class Text_二分插入排序 {

	public static void main(String[] args) {
   
   int[] array = {10,8,12,4,3};
   /*
    * 第一轮:i = 1
    * 初始:left 0  right 0  mid 0
    * 结束:left 0  right -1
    * 8 10 12 4 3
    * 第二轮: i = 2
    * 初始:left 0  right 0  mid 0
    * while执行一次:left 1  right 1  mid 1;
    * while执行二次:left 2  right 2
    * 8 10 12 4 3
    *    
    */
   //一共有多少数字要确定位置
   for (int i = 1; i < array.length; i++) { 
		//需要确定位置的数字
	    int temp = array[i];
	   //左边界初始化为0;
	    int left = 0;
		/*
		 * 有序数列的右边界,要确定位置的数字
		 * 之前都是有序的,右边界就是i-1
		 */
	    int right = i-1;
		int mid = (left + right) / 2;
		while(left <= right) {
			mid = (left + right) / 2;
		    if (array[mid] > temp) {
		//说明有序数列中中间数字比要确定位置的数字大		
		    	  right = mid - 1;
			} else {
				left = mid + 1;
			}
		} 
		//要确定位置的数字挪出位置
	      for (int j = i-1; j >= left; j--) {
			    array[j+1] = array[j];			 
		}  
	            array[left] = temp; 
   }	
	  System.out.println(Arrays.toString(array));
	 	
	   }
	}

7.java字符串

7.1)字符串出现次数

package java_字符串;

import java.util.HashMap;
import java.util.Scanner;

public class Text_字符出现次数 {

	public static void main(String[] args) {
 // 从控制台输入字符串,统计每个字符出现的次数	 
	Scanner scanner = new Scanner(System.in);
	 System.out.println("请输入字符串");
     String sc = scanner.next();
 // 创建map,将字符作为键,出现的次数作为值   
    HashMap<Character , Integer> map = new HashMap<>();
     for (int i = 0; i < sc.length(); i++) {
		 char ch = sc.charAt(i);
		    /*
			 * 如果是首次出现直接添加键值对
			 * 如果不是,在原有的基础上+1
			 */
		 // 不包含,第一次出现
	     if (!map.containsKey(ch)) {
			  map.put(ch, 1);
		} else {
		 // 不是第一次出现	
			map.put(ch, map.get(ch) + 1);
		} 
     }
	for (Character key : map.keySet()) {
		System.out.println(key + "(" + map.get(key) + ")");
	}
		
	}
}

7.2)统计小写字母,大写字母,数字出现次数

package java_字符串;

import java.util.Scanner;

public class Text_出现次数 {

	public static void main(String[] args) {
/*
 * 	控制台输入一段字符串,统计其中小写字母、
 * 大写字母、数字出现的的次数,例如:输入 abc123AVC
    输出:小写字母:3次  大写字母:3次  数字:3次	
 */
   Scanner scanner = new Scanner(System.in);
	  System.out.println("请输入");
	String string = scanner.next();
  //  字符数组不用加括号,字符串需要加括号	
	int[] count = new int[3];
	for(int i = 0; i < string.length(); i++){
		char c = string.charAt(i);
	  if( c >= 97 && c <= 122 ){
		  count[0]++; // 小写		  
	  }else if( c >= 65 && c <= 90 ){
		  count[1]++;  // 大写
	  } else if ( c >= 48 && c <= 57 ) {
		  count[2]++; // 数字
	  }	
	}
System.out.println("小写字母:" + count[0] + "次"  + " " 
	+ "大写字母:" + count[1] + "次" + " "
	+ "数字" + count[2] + "次" );	
	
	 }		
	}

7.3)反转

package java_字符串;

public class Text_反转 {

	public static void main(String[] args) {
		/*
		 * 编写程序将"test."变为"tset."
		 */
//    StringBuffer buffer = new StringBuffer("test");
//    System.out.println(buffer.reverse());
	
	/*
	 * 编写程序,将"To be or not to be" 变为
	 *   "oT eb ro ton ot eb" 每个单词都反转。
	 */	
	String str = "To be or not to be";
	String[] s1 = str.split(" "); //切割为字符串数组
	 String result = "";   //遍历数组为每个元素反转
	for(String item : s1 ){
	  StringBuilder sc = new StringBuilder(item);
	  StringBuilder sb = sc.reverse();  //反转	   
	  String s2 = sb.toString();
	   result = result + s2 + " ";
	}
	System.out.println(result);
	
	}
}

7.4)去重复的字母

public class Text_去重复字母 {

	public static void main(String[] args) {
 /*
  * 从控制台输入任意字母,将其中重复出现的字母去掉
  */
	 Scanner scanner = new Scanner(System.in);
	    System.out.println("请输入字母");
	    String sc = scanner.next();
	   String  result = "";
	   for(int i = 0; i < sc.length(); i++){
		   char c = sc.charAt(i);
		   int index = result.indexOf(c); //判断里面是否有需要字母
		 if(index == -1){
			 result = result + c;
		 }
		    
	   }
	   System.out.println(result); 
  }

7.5)首字母大写

public class Text_首字母大写 {

	public static void main(String[] args) {
      String string = "to be or not to be";
        // 切割为字符串数组
	  String[] str = string.split(" ");   //忘记[]
	    String result = "";
	  for(String item : str){
		 char first = item.charAt(0);
		     char sc = first;  // 小写转大写
		 if(first >= 97 && first <= 122){
			    sc = (char)( first -32 );
		 }
	  //  String 转化为StringBuider
	   StringBuilder  ss = new StringBuilder(item);
	  // 替换为大写          字符转化为字符串
	    ss.replace(0, 1, Character.toString(sc));	    	 
	   // 将StringBuider 转化为String 
	       item = ss.toString();    // 不要忘记转回来
	    result = result + item + " ";
	 }
		System.out.println(result);	
	}
}

7.6)小写转大写

public class Text_小写转大写 {

	public static void main(String[] args) {
     String string = "jdk";
	 String string2 = "";
	 for(int i = 0; i < string.length(); i++){
		char c = string.charAt(i); //得到原有字符
		char sc = c; //判断字符是否为小写,转换为大写
		if( 97 <= c && c <= 122 ){
			sc = (char)( c - 32 );
			string2 += sc;  // 将得到大写的字符拼接
		}
	}
		System.out.println(string2);
	}
}

7.7)Text练习

package java_字符串;

import java.awt.event.MouseWheelEvent;
import java.security.acl.Permission;
import java.text.AttributedString;

import javax.swing.plaf.synth.SynthToggleButtonUI;

import org.omg.CORBA.PUBLIC_MEMBER;
import org.omg.CORBA.portable.ValueBase;
/*
  * 一个源文件里面只能有一个被public修饰的类,
  * 被public修饰的方法可以有多个
  */
import org.omg.Messaging.SyncScopeHelper;
public class Text {

	public static void main(String[] args) {	
      Person person = new Person();
         person.name = "周帅";
         person.age = 30;     
      System.out.println(person.toString());
      	
	/*
	 * 	1.编写程序将"jdk"全部变为大写,输出;截取子串"DK" 并输出
	 */
//  方法一:
	    String string = "jdk";
	    String string2 = string.toUpperCase();
		System.out.println(string2);	 
 //方法二:
//	     String string = "jdk";
//	       String str = "";
//	for(int i =0; i < string.length(); i++){
//	  // 得到原有的字符
//		char c = string.charAt(i);
//	  // 先判断是否都是小写
//	    char bc = c;
//	    //将字符变为大写  ASCII码表  小写(97-122)  大写(65-90)
//	    if( 97 <= c && c <= 122 ){
//	    	    bc = (char)( c - 32 );  
//	    }		
//	//  将转换好的字符拼接
//		str += bc;	
//	}
//	   System.out.println(str);			
//		 String n = string2.substring(1);
//		 System.out.println(n);

	/*
	 * 2.编写程序将"test"变为"tset"
	 */
		StringBuffer sb = new StringBuffer("test");
		System.out.println(sb.reverse());
		
	/*
	 * 3.编写程序将"test."变为"tset."	
	 */    
//	 	String string = "test.";
//	 	string.toCharArray();
//	 	char[] ch =string.toCharArray();
//	 	char temp = ch[1];
//	 	  ch[1] = ch[2];
//	 	  ch[2] = temp;
//	   String result = new String(ch);
//	   System.out.println(result); 	
	
	 /*
	  * 5.编写程序,将"To be or not to be" 变为
	  *  "oT eb ro ton ot eb" 每个单词都反转。
	  */	
    // 每个单词反转
		String string = "To be or not to be";
	//切割为字符串数组
	 String[] s1 = string.split(" ");
	 //遍历数组,将每个元素反转
	  String result = "";
	for(String item : s1) {
		StringBuilder ss = new StringBuilder(item);
		StringBuilder sv = ss.reverse();
		String s2 = sv.toString();
		   result = result + s2 + " ";
	}
	 System.out.println(result);
		
	/*
	 * 将每个单词的首字母大写	
	 */ 
	// 每个单词反转
			String string = "To be or not to be";
		//切割为字符串数组
		 String[] strArray = string.split(" ");
		 //遍历数组,将每个元素反转
		  String result = "";
  for(String item: strArray){        //获取子字符串    大小写转化                  
			 String upFirst =  item.substring(0, 1).toUpperCase();
		     StringBuilder bf = new StringBuilder(item);  
		     bf.replace(0, 1, upFirst);
		     item = bf.toString();
		     result = result + item + " ";
		   }
		System.out.println(result);	
 for (String item: strArray){
		//得到首字母大写
		char first = item.charAt(0);
		      char bf = first;
		if(first >= 97 && first <= 122){
		    bf = (char)(first - 32);
	    // 用大写替换小写
		}
		 StringBuilder b = new StringBuilder(item);
	     b.replace(0, 1, Character.toString(bf));  
		        //Character.toString(bf) 字符转换成字符串	
		item = b.toString();
	 result = result + item + " " ; 
	}	
	System.out.println(result);
		
	/*
	 * 6.从控制台输入任意小写字母,将其中重复的出现的字母去掉。
	 */
	// 去重
		String str = "1123王yyTTToO";
	//接受结果
	 String result = "";
	 for(int i = 0; i < str.length(); i++){
		char c = str.charAt(i) ;
		int index = result.indexOf(c);  // 判断里面是否有需要字符
		if( index == -1 ){
			result = result + c;
		}
	 }
	 System.out.println(result);
	
	/*
	 * 7.从控制台输入一段字符串,统计其中小写字母、
	 * 大写字母、数字出现的的次数,例如:输入 abc123AVC
       输出:小写字母:3次  大写字母:3次  数字:3次

	 */
	String string = "123yyYY";
	int[] count = new int[3];
	for(int i = 0; i < string.length(); i++){
		char c = string .charAt(i);
	  if(c >= 97 && c <= 122){
		  count[0]++;  //小写
	  }else if( c >= 65 && c <= 90){    //大写
		  count[1]++;
	  }else if( c >= 48 && c <= 57){    // 数字
		  count[2]++;
	  }
	}
	System.out.println("小写"+ count[0] + "大写" + count[1] + "数字"+ count[2]);


字符串转换为字符数组
//public static char[]toCharArray(String str){
//	// 非null判断
//if ( str == null ) {
//	      System.out.println("字符");
//	       return null;
//}
 创建字符数组
//char[] charArray = new char[str.length()];
///*
// * 遍历字符串,
// * 将每个字符放到字符数组中
// */
//for( int i = 0; i < str.length(); i++ ){
//	 char c = str.charAt(i);
//	 charArray[i] = c;
//}
//   return charArray;
//}
//	}
   
	}
}

class Person {
	 String name;
	 int age;	 
	 @Override
	public String toString() {	
		String result = "name:"+ name + " " + "age:" + age;
		 return result;
	}
 }     

8.字符串拼接,得到字符串的长度,得到字符串中的某个字符,

   根据字符获取下标,查找子字符串,获取子字符串,

   判断字符串的开头/结尾,大小写转换,字符串切割

    将字符那串转化为字符数组

public class StringClass {

	public static void main(String[] args) {
     
        /*
		 * 字符串:== 比较的是内存地址 equals方法比较的是值      
		 */
		      
		/*
		 * <1>字符串拼接
		 */
		/*
		 * String 不可变字符串
		 * 当字符串的内容发生了改变,就会产生新的字符串
		 */
		String a = "ab";
		//参数只能是字符串
		a = a.concat("cde")	; //String b = a.concat("cde") ;
		a = a + (12 + 0.5);
		System.out.println(a);
		
		/*
		 * <2>得到字符串的长度(字符个数)      
		 */
		 String l = "程刚是个帅哥";
		 System.out.println(l.length());
		 
		 /*
		  * <3>得到字符串中的某个字符
		  */
		 //参数从0开始,到length-1;
		 // 打印时,字符串要加括号,数组不要加。
		for (int i = 0; i < l.length(); i++){
		         char c = l.charAt(i);
			System.out.print(c);	
			} 
		  System.out.println();
		  
      /* 
       * <4> 根据字符获得下标,
       *  如果方法的返回值为-1,说明没有找到从左开始找,找到第一个结束
       */	
		String str = "aabcde";
	  int index =str.indexOf('a');  // 左往右找	
    //int index = str.lastIndexOf('a'); //右往左找
	   System.out.println(index);
	
	/*
	 *<5>查找子字符串,
	 *返回的值为子串中第一个字符的位置将子串看作一个整体 	 
	 */
       int index = str.indexOf("bcd");
       System.out.println(index);
	 /*
	  * 第一个参数:要查找的字符或者字符串
	  * 第二个参数:查找的起始位置
	  */	
		int index = str.indexOf('a', 1);
		System.out.println(index);
		
	//<6>获取子字符串
    	String str = "abcde";
	 /*
	  *(1) 第一个参数是起始的下标(包含)
	  * 第二个参数是结束的下标(不包含)
	  */
	   String sub = str.substring(1, 3);
	//(2)从给定位置截取到最后
     	String  sub = str.substring(1);
	    System.out.println(sub);
		
  //<7>判断字符串的开头
     String url = "http://www.lanou3g.com";
     boolean start =	url.startsWith("dfdd");
       System.out.println(start);
    
  //<8>判断字符串的结尾
     boolean end = url.endsWith("com");
	   System.out.println(end);
	
  //<9>大小写转换
	    String string = "ZHUJGJ";
        string = string.toUpperCase();
	    System.out.println(string);
    //将大写转换为小写
	  String low = string.toLowerCase(); 
	   System.out.println(low);
	
  //<10>字符串切割
	 String ss  = "雨桐,宾格,杨洋,乐乐"; 
	 String[] names = ss.split(",");//参数:按照那个标准切割
	 System.out.println(Arrays.toString(names));
	 
 //<11>将字符串转换为字符数组
	String tt = "我是最棒的";
	char[] charArray = tt.toCharArray();
	    System.out.println(charArray);
	
	char[] arr = new char[tt.length()];	 
	for(int i = 0; i < tt.length(); i++) {
		 arr[i] = tt.charAt(i);
	 System.out.print(arr[i]);
	 } 
 }
}

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值