------- android培训、java培训、期待与您交流! ----------
class StringDemo
{
public static void main(String[] args)
{
String s1 = "abc";
//s1是一个类类型变量,“abc”是一个对象
//字符串最大特点:一旦被初始化就不可以被改变。
String s2 = new String("abc");
//面试:s1和s2有什么区别?
//答:s1在内存中有一个对象,s2在内存中有两个对象。
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
//String类复写了Object类中equals方法
//该方法用于判断字符串是否相同
}
}
String类适用于描述字符串事物,那么它就提供了多个方法对字符串进行操作
常见的操作有哪些?
"abcd"
1、获取(非常重要,必须掌握)
1.1字符串中的包含的字符数,也就是字符串的长度
int length():获取长度
1.2根据位置获取位置上某个字符
char charAt(int index):
1.3根据字符获取该字符在字符串中位置
int indexOf(int ch):返回的是ch在字符串中第一次出现的位置
int indexOf(int ch, int fromIndex):从fromIndex指定位置开始,获取ch在字符串中出现的位置。
int indexOf(String str):返回的是str在字符串中第一次出现的位置
int indexOf(String str,int fromIndex):从fromIndex指定位置开始,获取str在字符串中出现的位置。
int lastIndexOf(int ch):
2、判断
2.1字符串中是否包含某一个子串
boolean contains(str):【如果只用于判断就用这个】
特殊之处:indexOf(str):可以索引str第一次出现的位置,如果返回-1,表示该str不在字符串中存在。所以,也可以用于对指定判断是否包含。
if(str.indexOf("aa")!=-1)【既要判断又要拿位置用这个】而且该方法既可以判断,又可以获取出现的位置。
2.2字符中是否有内容
boolean isEmpty():原理就是判断长度是否为0。 "" null
2.3字符串是否是以指定内容开头
boolean startsWith(str);
2.4字符串是否是以指定内容结尾
boolean endsWith(str);
2.5判断字符串内容是否相同。复写了Object类中的equals方法
boolean equals(str);
2.6判断内容是否相同,并忽略大小写
boolean equalsIgnoreCase();
3、转换
3.1将字符数组转成字符串
构造函数:String(char[])
String(char[],offset,count):将字符数组中的一部分转成字符串
静态方法:
static String copyValueOf(char[]);
static String copyValueOf(char[] data,int offset, int count)
static String valueOf(char[]);
3.2将字符串转成字符数组
char[] toCharArray();
3.3将字节数组转成字符串
String(byte[])
String(byte[],offset,count);将字节数组中的一部分转成字符串
3.4将字符串转成字节数组
byte[] getBytes();
3.5将基本数据类型转成字符串
static String valueOf(int)
static String valueOf(double)
3+""; //String.valueOf(3);
特殊:字符串和字节数在转换过程中,是可以指定编码表的。
4、替换(必须记住)
String replace(oldchar,newchar)
5、切割(可以把字符串分开)
String[] split(regex);
6、子串。获取字符串中的一部分【掌握】
String substring(begin);
String substring(begin,end);
7、转换,去除空格,比较
7.1将字符串转成大写或者小写
String toUpperCase();
String toLowerCase();
7.2将字符串两端的多个空格去除
String trim();
7.3对两个字符串进行自然顺序的比较
int compareTo(string);
练习:字符串的这些功能必须会,必须达到不查阅API文档,不借助Eclipse高级工具,也能熟练应用。
1、模拟一个trim方法,去除字符串两端的空格
思路:
(1)判断字符串第一个位置是否是空格,如果是继续向下判断,直到不是空格为止,结尾处判断空格也是如此。
(2)当开始和结尾都判断到不是空格时,就是要获取的字符串
class StringTest
{
public static void sop(String str)
{
System.out.println(str);
}
public static void main(String[] args)
{
String s = " ab cd ";
sop("("+s+")");
sop("("+reverseString(s)+")");
}
//练习一:去除字符串两端空格
public static String myTrim(String str)
{
int start = 0,end = str.length()-1;
while(start<=end && str.charAt(start)==' ')
start++;
while(start<=end && str.charAt(end)==' ')
end--;
return str.substring(start,end+1);
}
}
2、将一根字符串进行反转,将字符串中指定部分进行反转,“abcdefg”;abfedcg
思路:
(1)曾经学习过对数组的元素进行反转
(2)将字符串变成数组,对数组反转
(3)将反转后的数组变成字符串
(4)只要将反转的部分的开始和结束位置作为参数传递即可
class StringTest
{
public static void sop(String str)
{
System.out.println(str);
}
public static void main(String[] args)
{
String s = " ab cd ";
sop("("+s+")");
sop("("+reverseString(s)+")");
}
public static String reverseString(String s,int start,int end)
{
//字符串变数组
char[] chs = s.toCharArray();
//反转数组
reverse(chs,start,end);
//将数组变成字符串
return new String(chs);
}
public static String reverseString(String s)
{
return reverseString(s,0,s.length());
}
private static void reverse(char[] arr,int x,int y)
{
for(int start=x,end=y-1;start<end;start++,end--)
//java但凡取从头到尾的部分,是包含头不包含尾的。
{
swap(arr,start,end);
}
}
private static void swap(char[] arr,int x,int y)
{
char temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
3、获取一个字符串在另一个字符串中出现的次数"abkkcdkkefkkskk"
思路:
(1)定义个计数器
(2)获取kk第一次出现的位置
(3)从第一次出现位置后剩余的字符串中继续获取kk出现的位置
每获取一次就计数一次
(4)当获取不到时,计数完成
class StringTest2
{
/*
练习三,方式一
*/
public static int getSubCount(String str,String key)
{
int count = 0;
int index = 0;
while((index=str.indexOf(key))!=-1)
{
sop("str="+str);
str = str.substring(index+key.length());
count++;
}
return count;
}
/*
练习三,方式二:
*/
public static int getSubCount_2(String str,String key)
{
int count = 0;
int index = 0;
while((index=str.indexOf(key,index))!=-1)
{
sop("index="+index);
index = index + key.length();
count++;
}
return count;
}
public static void main(String[] args)
{
String str = "kkabkkcdkkefkks";
//sop("count====="+str.split("kk").length);不建议使用
sop("count="+getSubCount_2(str,"kk"));
}
public static void sop(String str)
{
System.out.println(str);
}
}
4、获取两个字符串中最大相同子串。第一个动作:将短的那个串进行长度依次递减的子串打印
"abcwerthelloyuiodef"
"cvhellobnm"
思路:
(1)将短的那个子串按照长度递减的方式获取到
(2)将每次获取到的子串去长串中判断是否包含, 如果包含,已经找到!
class StringTest3
{
public static String getMaxSubString(String s1,String s2)
{
String max = "",min = "";
max = (s1.length()>s2.length())?s1: s2;
min = (max==s1)?s2 :s1;
//sop("max="+max+"...min="+min);
for(int x=0; x<min.length();x++)
{
for(int y=0,z=min.length()-x; z!=min.length()+1; y++,z++)
{
String temp = min.substring(y,z);
//sop(temp);
if(max.contains(temp))//if(s1.indexOf(temp)!-1)
return temp;
}
}
return "";
}
public static void main(String[] args)
{
String s1 = "ab";
String s2 = "cvhellobnm";
sop(getMaxSubString(s2,s1));
}
public static void sop(String str)
{
System.out.println(str);
}
}
StringBuffer是字符串缓冲区
是一个容器,特点:
1、长度是可变化的
2、可以直接操作多个数据类型
3、最终会通过toString方法变成字符串
什么时候用?
当数据类型不确定,而且变成字符串的时候,而且数据的个数也不确定
C create U updata R read D delete
1、存储
StringBuffer append():将制定数据作为参数添加到已有数据结尾处
StringBuffer insert(index,数据):可以将数据插入到指定index位置
缓冲区的面盆理论:盆就是StringBuffer,往里面添加东西,添加完还是这盆。
2、删除
StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end
StringBuffer deleteCharAt(index):删除指定位置的字符
3、获取
char charAt(int index)
int indexOf(String str)
int lastIndexOf(String str)
int length()s
String substring(int start,int end)
4、修改
StringBuffer replace(start,end,string);
void setCharAt(int index,char ch);
5、反转
StringBuffer reverse();
6、将缓冲区中指定数据存储到指定字符数组中
void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin)
JDK1.5版本后出现了StringBuilder
StringBuffer是线程同步(建议多线程使用)
StringBuilder是线程不同步(建议单线程使用)
以后开发,建议使用StringBuilder
升级三个因素
1、提高效率 2、简化书写 3、提高安全性
/*
JDK1.5版本以后出现的新特性
*/
class IntegerDemo1
{
public static void main(String[] args)
{
//Integer x = new Integer(4);
Integer x = 4;//自动装箱 //new Integer(4)
//Integer x = null;//空指针异常,一定要注意
x = x/*x.intValue()*/ + 2;//x+2:x 进行自动拆箱,
//变成了int类型和2进行加法运算,再将和进行装箱赋给x。
Integer m = 128;
Integer n = 128;
sop("m==n:"+(m==n));
Integer a = 127;
Integer b = 127;
sop("a==b:"+(a==b));
//结果为true.因为a和b指向了同一个Integer对象。
//因为当数值在byte范围内时,对于新特性,如果该数值已经存在,
//则不会再开辟新空间。
}
public static void method()
{
Integer x = new Integer("123");
Integer y = new Integer(123);
sop("x==y:"+(x==y));
sop("x.equals(y):"+x.equals(y));
}
public static void sop(String str)
{
System.out.println(str);
}
}
Collection
|--List:元素是有序的,元素可以重复,因为该集合体系有索引
|--ArrayList:底层的数据结构使用的是数组结构
特点:查询速度很快,但是增、删稍慢。线程同步
|--LinkedList:底层使用的链表数据结构
特点:增、删速度很快,查询稍慢
|--Vector:底层是数组数据结构。线程同步。
被ArrayList替代了。
|--Set:元素是无序,元素不可以重复。
List:
特有方法,凡是可以操作角标的方法都是该体系特有的方法
增:add(index,element);
addAll(index,Collection);
删:
remove(index);
改:
set(index,element);
查:
get(index);
subList(from,to);
listIterator();
List集合特有的迭代器。ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素
因为会发生ConcurrentModificationException异常
所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator.该接口只能通过List集合的listIterator方法获取
import java.util.*;
class ListDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void method()
{
ArrayList al = new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
sop("原集合是:"+al);
//在指定位置添加元素
al.add(1,"java09");
//删除指定位置的元素
//al.remove(2);
//修改元素
//al.set(2,"java007");
//通过角标获取元素
sop("get(1):"+al.get(1));
sop(al);
//获取所有元素
for(int x=0; x<al.size();x++)
{
System.out.println("al("+x+")="+al.get(x));
}
Iterator it = al.iterator();
while(it.hasNext())
{
sop("next:"+it.next());
}
//通过indexOf获取对象的位置
sop("index="+al.indexOf("java02"));
List sub = al.subList(1,3);
sop("sub="+sub);
}
public static void main(String[] args)
{
//演示列表迭代器
ArrayList al = new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
sop(al);
ListIterator li = al.listIterator();
//sop("hasPrevious():"+li.hasPrevious());
while(li.hasNext())
{
Object obj = li.next();
if(obj.equals("java02"))
//li.add("java009");
li.set("java006");
}
while(li.hasPrevious())
{
sop("pre::"+li.previous());
}
//sop("hasNext():"+li.hasNext());
//sop("hasPrevious():"+li.hasPrevious());
sop(al);
/*
//在迭代过程中,准备添加或者删除元素
Iterator it = al.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(obj.equals("java02"))
//al.add("java008");
it.remove();//将java02的引用从集合中删除了。
sop("obj="+obj);
}
*/
//sop(al);
}
}
面试:
LinkedList:特有方法
addFirst();
addLast();
getFirst();
getLast();
获取元素,但不删除元素
如果集合中没有元素,会出现NoSuchElementException.
removeFirst();
removeLast();
获取元素,但是元素被删除。
如果集合中没有元素,会出现NoSuchElementException.
在JDK1.6出现了替代方法
offerFirst();
offerLast();
peekFirst();
peekLast();
获取元素,但不删除元素。如果集合中没有元素,返回null。
pollFirst();
pollLast();
获取元素,但是元素被删除。如果集合中没有元素,返回null.
import java.util.*;
class LinkedListDemo
{
public static void main(String[] args)
{
LinkedList link = new LinkedList();
link.addLast("java01");
link.addLast("java02");
link.addLast("java03");
link.addLast("java04");
while(!link.isEmpty())
{
sop(link.removeLast());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
使用LinkedList模拟一个堆栈或者队列数据结构
堆栈:先进后出 如同一个杯子
队列:先进先出 First in First out FIFO如同一个水管
import java.util.*;
class DuiLie
{
private LinkedList link;
DuiLie()
{
link = new LinkedList();
}
public void myAdd(Object obj)
{
link.addFirst(obj);
}
public Object myGet()
{
return link.removeFirst();//必须会
return link.removeLast();//必须会
}
public boolean isNull()
{
return link.isEmpty();
}
}
class LinkedListTest
{
public static void main(String[] args)
{
DuiLie dl = new DuiLie();
dl.myAdd("java01");
dl.myAdd("java02");
dl.myAdd("java03");
dl.myAdd("java04");
while(!dl.isNull())
{
System.out.println(dl.myGet());
}
}
}
List集合判断元素是否相同,依据是元素的equals方法。
增、删操作频繁,用LinkedList
增、删操作不频繁,用ArrayList和LinkedList都行
既有增删又有查询,建议用ArrayList
|--Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复
|--HashSet:底层数据结构是哈希表
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。先依赖hashCode,再依赖equals。
如果元素的HashCode值相同,才会判断equals是否为true,如果元素的hashCode值不同,不会调用equals.
注意,对于判断元素是否存在,已经删除等操作,依赖的方法是元素的hashcode和equals 方法。
面试:HashSet集合判断元素是否相同或者保证唯一性依赖什么方法?
答:如上
|--TreeSet:
Set集合的功能和Collection是一致的。
在开发的时候,需要描述事物向集合里面存的时候,一般都复写hashCode和equals.
ArrayList判断元素是否相同或者存储重复元素 只依赖equals.
ArrayList判断元素是否存在或者删除元素 只依赖equals。想删元素,想判断元素,都必须先判断哈希值,这就是哈希表的特点。
import java.util.*;
class HashSetDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
sop(hs.add("java01"));
sop(hs.add("java01"));
hs.add("java02");
hs.add("java03");
hs.add("java03");
hs.add("java04");
Iterator it = hs.iterator();
while(it.hasNext())
{
sop(it.next());
}
}
}
import java.util.*;
/*
往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。
*/
class HashSetTest
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
//hs.add(new Person("a2",12));
//hs.add(new Person("a4",14));
//sop("a1:"+hs.contains(new Person("a2",12)));
hs.remove(new Person("a4",13));
Iterator it = hs.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public int hashCode()
{
System.out.println(this.name+"......hashCode");
return name.hashCode()+age*39;
//return 60;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"...equals..."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}