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]);
}
}
}