黑马程序员————学习日记【9】 【String和ArrayList】

------- 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;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值