建议查手册
字符串缓冲区,用于存储数据的容器
增删改查:C(create)U(update)R(read)D(delete)
添加
删除
查找
修改
jdk1.5以后出现的与StringBuffer兼容的对象,为了解决StringBuffer因线程同步而导致的效率低,但在多线程下还是建议使用StringBuilder。局部变量不存在线程安全问题,所以建议使用StringBuilder
字符串对象一旦被初始化就不会被改变
String s1 = "abc";// 字符串常量池中的地址
String s2 = new String("abc");// 新建对象的内存地址
System.out.println(s1 == s2);// false
System.out.println(s1.equals(s2));// true // string类的equals复写了object中的equals方法,
// 建立了string类自己的判断字符串对象是否相同的依据
String s = new String();// 等价于String s = "";,但不等价String = null;
String s = "张三,李四,王五";
String[] arr = s.split(",");
//不能为点,因为点在正则中是特殊符号
//如果一定要用点分割的话,要"\\."
for (int i=0;ichar[] chs = s.toCharArray();
for (int i=0;i"ab你";
for (int i=0;i
System.out.println("abc".contact("kk"));
System.out.println("abc"+"kk");
//在进行大量的字符串连接时,效率会变低,所以开发推荐使用contact方法
System.out.println(String.valueOf(4)+1);
System.out.println(" "+4+1);
//intern():对字符串池进行操作的
String s1 = new String("abc");
String s2 = s1.intern();
System.out.println(s1 == s2);// false
1.给定一个字符串数组,按字典顺序进行从小到大排序
public static void main(String[] args){
String[] arr = {"abc","af","asd","wae","ww"};
printArray(arr);
sortString(arr);
printArray(arr);
}
public static void printArray(String[] arr){
System.out.print("[");
for (int i=0;iif(i!arr.lenth-1){
System.out.println(arr[i]);
}else{
System.out.println(arr[i]+"]");
}
}
}
public static void sortString(String[] arr){
for (int i=0;i1;i++){
for (int j=i+1;jif (arr[i].compareTo(arr[j]) > 0){
swap(arr,i,j);
}
}
}
}
public static void swap(String[] arr,int i,int j){
String temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
2.一个子串在整串中出现的次数
/*
COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.javase.commclass;
/**
* 一个子串在整串中出现的次数
*
* @author Hoki_Lin
* @since 1.0
*/
public class StringTest1 {
public static void main(String[] args) {
String str = "jlfajldjfljlfjaljlf";
String key = "jlf";
int count = getKeyStringCount(str, key);
System.out.println(count);
}
/**
* 获取子串在整串中出现的次数
*
* @param str
* @param key
* @return count
*/
public static int getKeyStringCount(String str, String key) {
// 1. 定义计数器
int count = 0;
// 2. 定义变量记录key出现的位置
int index = 0;
while ((index = str.indexOf(key, index)) != -1) {
index += key.length();
count++;
}
return count;
}
}
3.两个字符串中最大相同的子串
/*
COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.javase.commclass;
/**
* 两个字符串中最大相同的子串
*
* @author Hoki_Lin
* @since 1.0
*/
public class StringTest2 {
public static void main(String[] args) {
String s1 = "asdfadffafafad";
String s2 = "asewadfffadf";
String s = getMaxSubstring(s1, s2);
System.out.println(s);
}
public static String getMaxSubstring(String s1, String s2) {
String max = null, min = null;
max = (s1.length() > s2.length()) ? s1 : s2;
min = max.equals(s1) ? s2 : s1;
for (int i = 0; i < min.length(); i++) {
for (int a = 0, b = min.length() - i; b != min.length() + 1; a++, b++) {
String sub = min.substring(a, b);
if (max.contains(sub)) {
return sub;
}
}
}
return null;
}
}
4.模拟一个trim功能一致的方法
/*
COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.javase.commclass;
/**
* 模拟一个trim功能一致的方法
*
* @author Hoki_Lin
* @since 1.0
*/
public class StringTest3 {
public static void main(String[] args) {
String s = " ad d ";
s = myTrim(s);
System.out.println(s);
}
public static String myTrim(String s) {
int start = 0, end = s.length() - 1;
while (start <= end && s.charAt(start) == ' ') {
start++;
}
while (start <= end && s.charAt(end) == ' ') {
end--;
}
return s.substring(start, end + 1);
}
}
对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定,就使用集合容器进行存储
集合容器因为内部的数据结构不同,有多种具体容器,不断地向上抽取,就形成了集合框架,框架的顶层就是Collection接口
这个时候就得看手册了
public class CollectionDemo {
public static void main(String[] args) {
Collection coll = new ArrayList();
show(coll);
}
private static void show(Collection coll) {
// 1.添加元素
coll.add("asdf1");
coll.add("asdf2");
coll.add("asdf3");
System.out.println(coll);
// 2.移除元素
coll.remove("asdf2");
System.out.println(coll);
// 3.清空集合
coll.clear();
System.out.println(coll);
// 4.是否包含某个元素
System.out.println(coll.contains("asdf4"));// false
}
}
public class CollectionDemo2 {
public static void main(String[] args) {
Collection c1 = new ArrayList();
Collection c2 = new ArrayList();
show2(c1,c2);
}
private static void show2(Collection c1, Collection c2) {
// 给c1添加元素
c1.add("asdf1");
c1.add("asdf2");
c1.add("asdf3");
// 给c2添加元素
c2.add("asdf2");
c2.add("asdf3");
c2.add("asdf6");
// addAll方法将c2的元素添加到c1中
c1.addAll(c2);// 元素可重复
System.out.println(c1);// [asdf1, asdf2, asdf3, asdf2, asdf3, asdf6]
// removeAll方法会将两个集合中的相同元素从调用removeAll的集合中删除
System.out.println(c1.removeAll(c2));// true
System.out.println(c1);// [asdf1]
// retainAll方法可取两个集合的交集
System.out.println(c1.retainAll(c2));// true
System.out.println(c1+" ");// [asdf2, asdf3]
}
}
/*
COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* 迭代器的基本使用
*
* @author Hoki_Lin
* @since 1.0
*/
public class IteratorDemo {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("asdf1");
coll.add("asdf2");
coll.add("asdf3");
coll.add("asdf4");
/*
* Iterator it = coll.iterator();
*
* while(it.hasNext()){ System.out.println(it.next()); }
* System.out.println(it.next());// 抛出异常,证明while中的迭代器在循环结束后依旧占用内存
*/
// 开发中使用for循环来迭代较安全
for (Iterator it = coll.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}
Iterator该对象必须依赖于具体容器,因为每一个容器的数据解耦股都不同,所以该迭代器对象时在容器中进行内部实现的,对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,也就是iterator方法。Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
List中的元素存入和取出都有序,且元素有索引可重复;List中特有的常见方法就是可以操作索引。
/*
* COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.collection;
import java.util.ArrayList;
import java.util.List;
/**
* List的常见方法演示
*
* @author Hoki_Lin
* @since 1.0
*/
public class ListDemo {
public static void main(String[] args) {
List list = new ArrayList();
show(list);
}
private static void show(List list ) {
// 插入元素
list.add("asdf1");
list.add("asdf2");
list.add("asdf3");
list.add("asdf4");
// 按索引插入元素
list.add(1,"插入成功");
// 删除元素
System.out.println("删除元素:"+list.remove(2));
// 修改元素
System.out.println("修改元素:"+list.set(1, "修改成功"));
// 获取元素
System.out.println("获取元素:"+list.get(0));
System.out.println(list);
// 获取子列表
System.out.println("子列表(左闭右开):"+list.subList(1, 2));
}
}
main(){
Integer it1 = new Integer("3");
Integer it2 = new Integer(3);
System.out.println(it1.equals(it2));//true
}
main(){
int num = 4;
num = num + 5;
Integer i = 4;//i = new Integer(4);自动装箱,简化了书写
i = i + 6;//i = new Integer(i.intValue() + 6);自动拆箱
}
JDK1.5以后,自动装箱,如果装箱的是一个字节,那么该数据会被共享不会重新开辟空间
main(){
Integer x = 127;
Integer y = 127;
System.out.println(x==y);//true
System.out.println(x.equals(y));//true
Integer x = 128;
Integer y = 128;
System.out.println(x==y);//false
System.out.println(x.equals(y));//true
}
/*
* COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.collection;
import java.util.Arrays;
/**
* 对一个字符串中的数值进行从小到大的排序
*
* @author Hoki_Lin
* @since 1.0
*/
public class WrappTest {
public static void main(String[] args) {
String numStr = "22 34 4 34 55 7 -1";
System.out.println(numStr);
numStr = sortStringNumber(numStr);
System.out.println(numStr);
}
private static final String SPACE_SEPARATOR = " ";
/**
* 对一个字符串中的数值进行从小到大的排序
*
* @param numStr
* @return
*/
public static String sortStringNumber(String numStr) {
// 1.将字符串变成字符串数组
String[] str_arr = stringToArray(numStr);
// 2.将字符串数组变成int数组
int[] num_arr = toIntArray(str_arr);
// 3.对int数组排序
mySortArray(num_arr);
// 4.将排序后的int数组变成字符串
return arrayToString(num_arr);
}
public static String arrayToString(int[] num_arr) {
StringBuilder sb = new StringBuilder();
for (int x = 0; x < num_arr.length; x++) {
if (x != num_arr.length - 1) {
sb.append(num_arr[x] + SPACE_SEPARATOR);
} else {
sb.append(num_arr[x]);
}
}
return sb.toString();
}
/**
* 对int数组排序
*
* @param num_arr
*/
public static void mySortArray(int[] num_arr) {
Arrays.sort(num_arr);
}
/**
* 将字符串数组变成int数组
*
* @param str_arr
* @return
*/
public static int[] toIntArray(String[] str_arr) {
int[] arr = new int[str_arr.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(str_arr[i]);
}
return arr;
}
/**
* 将字符串变成字符串数组
*
* @param numStr
* @return
*/
public static String[] stringToArray(String numStr) {
return numStr.split(SPACE_SEPARATOR);
}
}
public class ListDemo2 {
public static void main(String[] args) {
List list = new ArrayList();
// show(list);
list.add("asdf1");
list.add("asdf2");
list.add("asdf3");
list.add("asdf4");
System.out.println(list);
// 列表迭代器可以实现在迭代过程中完成对元素的增删查改,只有list集合具备该迭代功能
ListIterator it = list.listIterator();// 获取列表迭代器
while (it.hasNext()) {
Object obj = it.next();
if (obj.equals("asdf2")) {
// it.add("asdf9");
it.set("asdf9");
}
}
System.out.println(list);
// System.out.println("hasNext:"+it.hasNext());
// System.out.println("hasPrevious:"+it.hasPrevious());
while (it.hasPrevious()) {
System.out.println("previous:" + it.previous());
}
System.out.println("list:" + list);
/*
* // 在迭代器过程中,不要使用集合操作元素,容易出现异常 //
* 可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作 Iterator it =
* list.iterator(); while(it.hasNext()){ Object obj = it.next();//
* java.util.ConcurrentModificationException if(obj.equals("asdf2")){
* list.add("asdf9"); }else{ System.out.println("next:"+obj); } }
* System.out.println(list);
*/
}
public static void show(List list) {
list.add("asdf1");
list.add("asdf2");
list.add("asdf3");
list.add("asdf4");
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// list特有的取出元素之一
for (int x = 0; x < list.size(); x++) {
System.out.println("get:" + list.get(x));
}
}
}
List常用子类 | 特点 |
---|---|
Vector | 内部是数组数据结构,是同步的,增删、查询都很慢 |
ArrayList | 内部是数组数据结构,是不同步的,替代了Vector,查询的速度快 |
LinkedList | 内部是双向链表数据结构,是不同步的,增删元素的速度快 |
public class VectorDemo {
public static void main(String[] args) {
Vector v = new Vector();
v.addElement("asdf1");
v.addElement("asdf2");
v.addElement("asdf3");
v.addElement("asdf4");
// Enumeration与Iterator接口的功能是重复的,但推荐使用Iterator接口,理由查手册
Enumeration en = v.elements();
while (en.hasMoreElements()) {
System.out.println(en.nextElement());
}
}
}
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList link = new LinkedList();
link.addFirst("asdf1");
link.addFirst("asdf2");
link.addFirst("asdf3");
link.addFirst("asdf4");// 最后插入进头
// 获取第一个元素但不删除
System.out.println(link);
System.out.println(link.getFirst());
// 获取第一个元素并删除
System.out.println(link.removeFirst());
System.out.println(link);
while (!link.isEmpty()) {
System.out.println(link.removeFirst());
}
System.out.println(link);
// Iterator it = link.iterator();
// while(it.hasNext()){
// System.out.println(it.next());
// }
}
}
快捷键:alt+shift+s
public class ArrayListTest {
public static void main(String[] args) {
ArrayList al = new ArrayList();
// add方法接收的是Object
al.add(new Person("list1", 21));
al.add(new Person("list2", 21));
al.add(new Person("list3", 21));
Iterator it = al.iterator();
while (it.hasNext()) {// next方法会自动走到下一个,所以最好只写一个
// 向下转型为Person
Person p = (Person) it.next();
System.out.println(p.getName() + "--" + p.getAge());
}
}
}
元素不可重复,是无序;Set接口中的方法和Collection一致
常用子类 | 特点 |
---|---|
HashSet | 内部数据结构是哈希表,是不同步的 |
TreeSet | 内部数据结构是二叉树,是不同步的 |
public class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add("hehe");
hs.add("uu");
hs.add("asdf");
hs.add("qwer");
hs.add("hehe");
hs.add("uu");
hs.add("asdf");
hs.add("qwer");
Iterator it = hs.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
public class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
/*
* HashSet集合数据结构是哈希表,所以存储元素的时候,
* 使用的元素的hashCode方法来确定位置,如果位置相同,再通过元素的equals来确定是否相同
*/
System.out.println("-------------添加--------------");
hs.add(new Person("asdf1", 23));
hs.add(new Person("asdf2", 26));
hs.add(new Person("asdf3", 29));
hs.add(new Person("asdf4", 21));
System.out.println("-------------重复元素会比较内容--------------");
hs.add(new Person("asdf4", 21));
Iterator it = hs.iterator();
System.out.println("-------------输出------------");
while (it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName() + "..." + p.getAge());
}
}
}
public class Person {
private String name;
private int age;
@Override
public int hashCode() {
System.out.println(this + "...hashCode");
return name.hashCode() + age;
}
@Override
public boolean equals(Object obj) {
System.out.println(this + "...equals..." + obj);
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return name + ":" + age;
}
}
无论想要删除一个元素,还是想要包含一个元素是否存在,最终都要落实到一个问题上:该元素是否有和该容器中的元素相同,那么就得看该容器判断元素相同的依据。对于ArrayList的集合判断equals,对于HashSet的集合判断hashCode和equals。
/*
* COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
/**
* 唯一且有序地输出
*
* @author Hoki_Lin
* @since 1.0
*/
public class LinkedHashSetDemo {
public static void main(String[] args) {
HashSet hs = new LinkedHashSet();
hs.add("hehe");
hs.add("uu");
hs.add("asdf");
hs.add("qwer");
hs.add("hehe");
hs.add("uu");
hs.add("asdf");
hs.add("qwer");
Iterator it = hs.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
使用元素的自然顺序对元素进行排序,是不同步的
TreeSet判断元素唯一性的方式就是根据比较方法的返回结果是否是0,如果是0,就是相同元素,不存储
让元素自身具备比较功能,元素就需要实现Comparable接口,覆盖compareTo方法
/*
* COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.collection;
/**
* bean
*
* @author Hoki_Lin
* @since 1.0
*/
public class Person implements Comparable {
private String name;
private int age;
@Override
public int hashCode() {
// System.out.println(this + "...hashCode");
return name.hashCode() + age;
}
@Override
public boolean equals(Object obj) {
// System.out.println(this + "...equals..." + obj);
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return name + ":" + age;
}
public int compareTo(Object o) {
Person p = (Person) o;
int temp = this.age - p.age;// 这里整数相减的返回结果只有三种结果:-1, 0 , 1
return temp == 0 ? this.name.compareTo(p.name) : temp;
}
}
/*
* COPYRIGHT (C) 2018 BY HOKI SOFTWARE. ALL RIGHTS RESERVED.
*/
package com.hoki.collection;
import java.util.Iterator;
import java.util.TreeSet;
/**
* TreeSet本身是对元素的字典顺序排序的
*
* @author Hoki_Lin
* @since 1.0
*/
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
// 以Person对象的年龄进行从小到大的排序且可以有重复的元素
ts.add(new Person("zhangsan", 28));
ts.add(new Person("wangwu", 28));
ts.add(new Person("lisi", 21));
ts.add(new Person("zhouqi", 29));
ts.add(new Person("zhaoliu", 25));
Iterator it = ts.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName() + ":" + p.getAge());
}
/* 输出结果:
* lisi:21
zhaoliu:25
wangwu:28
zhangsan:28
zhouqi:29*/
}
}
如果不要按照对象中具备的自然顺序进行排序;
如果对象中不具备自然顺序,那该如何解决?
可以使用TreeSet集合第二种排序方式:让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeSet集合的构造函数。比较器的优先级要高与对象本身的Comparable接口的方法。
public class TreeSetTest {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new ComparatorByLength());
ts.add("aaaaaa");
ts.add("zz");
ts.add("nbag");
ts.add("cba");
ts.add("abc");
ts.add("abcd");
Iterator it = ts.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
public class ComparatorByLength implements Comparator{
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
int temp = s1.length()-s2.length();
return temp==0?s1.compareTo(s2):temp;
}
}