JavaDay10 ==和equals,分隔符接口,统计字符串,集合--练习

1. 分析下面程序的运行结果。

理解"=="和equals()方法的区别:
(1)等等比较的是值,基本数据类型的值,或者引用类型的地址值;
(2)equals()方法默认方法底层也是等等实现的,但可以重写。

String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
String str4 = new String("hello");
String str5 = "hellohello";
String str6 = str1 + str2;
System.out.println("str1==str2?" + (str1 == str2));//true
System.out.println("str2==str3?" + (str2 == str3)); //false
System.out.println("str3==str4?" + (str3 == str4));//false
System.out.println("str2.equals(str3)?" + (str2.equals(str3))); //true
System.out.println("str3.equals(str4)?" + (str3.equals(str4))); //true
System.out.println(str5.equals(str6));//true
System.out.println(str5 == str6);//false

String s1 = "helloworld";
String s2 = "hello";
String s3 = "world";
String s4 = "hello" + "world";
String s5 = s2 + s3;
String s6 = new String("helloword");
String s7 = "hello" + new String("world");
System.out.println(s1 == s4);//true
System.out.println(s1 == s5);//false
System.out.println(s1 == s6);//false
System.out.println(s1 == s7);//false

2. 将接口实现并完成规定的功能:

public interface Action{ 
	public String[] test(String str);
}

对该接口进行实现,让其可以具有处理以下两种字符串的功能:
(1)可以把字符串按照 | 进行分割,并得到数组;例如:a|b|c
(2)可以把字符串按照 - 进行分割,并得到数组;例如:a-b-c
要求使用匿名内部类的方式完成:

//1.接口中重写方法实现分割
public class ActionImpl{
	public static void main(String[] args) {
		Action a = new Action() {
		@Override
		public String[] test(String str) {
			String[] strs = null;
			if(str.contains("|")) {
				strs = str.split("\\|");
			}else if(str.contains("-")) {
				strs = str.split("[-]");
			}
			return strs;
		};
		String[] test = a.test("a|b|c");
		System.out.println(Arrays.toString(test));
	}
}
//2.1定义一个分隔符接口:
package com.briup.day11;
import java.util.Arrays;
/**
 * @author chouhan
 */
public interface SeparatorAction {
	//定义一个返回值为字符串数组的有参的抽象方法
	public String[] test(String str);
}
//定义一个实现类继承这个接口
class TestSeparatorAction implements SeparatorAction{
	//重写这个接口的抽象方法
	@Override
	public String[] test(String str) {
		//split方法:split(String regex),regex是分隔符 
		//将此字符串分割为给定的 regular expression的匹配。
		//定义"|"作为分隔符,把传入的字符串用|分割后传给字符串数组arr
		String[] arr=str.split("[|]");
		//把得到的新数组转换为字符串输出
		System.out.println(Arrays.toString(arr));
		return arr;
	}
}
//再定义一个实现类继承这个接口
class TestSeparatorAction2 implements SeparatorAction{
	//重写这个接口的抽象方法
	@Override
	public String[] test(String str2) {
		//定义"-"作为分隔符,把传入的字符串用-分割后传给字符串数组arr2
		String[] arr2=str2.split("[-]");
		//把得到的新数组转换为字符串输出
		System.out.println(Arrays.toString(arr2));
		return arr2;
	}
}
//2.2测试分隔符接口:
package com.briup.day11;
/**
 * @author chouhan
 */
public class TestAction {
	public static void main(String[] args) {
		//创建对象分别调用这两个类进行测试
		TestAction testAction=new TestAction();
		testAction.test(new TestSeparatorAction(), "a|b|c");
		TestAction testAction2=new TestAction();
		testAction2.test2(new TestSeparatorAction2(), "a-b-c");
	}
	//定义一个测试类,调用这个接口的实现类1的方法
	public String[] test(TestSeparatorAction t,String s) {
		return t.test(s);
	}
	//再定义一个测试类,调用这个接口的实现类2的方法
	public String[] test2(TestSeparatorAction2 t2,String s2) {
		return t2.test(s2);
	}
}

3. 、编写程序:由键盘录入一个字符串,统计字符串中英文字母和数字分别有多少个。(比如:Hello12345World中,字母:10个,数字:5个)

public static void main(String[] args) {
	System.out.println("请输入你想输入的字符串:");
	Scanner sc = new Scanner(System.in);
	String str = sc.nextLine();
	// 将所有的字母转换成小写
	str = str.toLowerCase();
	// 接收数字
	int numberCount = 0;
	// 接收字母
	int letterCount = 0;
	for (int i = 0; i < str.length(); i++) {
		char at = str.charAt(i);
		if (at >= '0' && at <= '9') {
			numberCount++;
		} else if (at >= 'a' && at <= 'z') {
			letterCount++;
		}
	}
	System.out.println(str + "中字母有" + letterCount + "个,数字有" + numberCount +"个");
}

集合

1. LinkedList、Vector、ArrayList的区别?

  1. 从存储数据结构分析:
    (1)ArrayList:数组;Vector:数组;LinkedList:双向链表。
    (2)数组:可以根据下标快速查找,所以大部分情况下,查询快。但是如果要进行增删操作的时候,会需要移动修改元素后面的所有元素,所以增删的开销比较大,数组的对增删操作的执行效率低。而采用数组作为数据存储结构的ArrayList、Vector也存在这些特性,查询速度快(可以根据下标直接取,比迭代查找更快),增删慢。
    (3) 链表:增加和删除元素方便,增加或删除一个元素,仅需处理结点间的引用即可。就像人手拉手连成一排,要增加或删除某个人只要附近的两个人换一个人牵手,对已经牵好手的人没影响。无论在哪换人,耗费的资源和时间都是一样的。但是查询不方便,需要一个个对,无法根据下标直接查找。而采用链表结构存储 LinkedList 有这些特性,增删方便,查询慢(指的是随机查询,不是顺序查询)。

  2. 从并发安全上分析:
    (1)Vector:线程安全,加了锁:synchronized,但效率低了;
    (2) ArrayList:非线程安全,效率高;
    (3)LinkedList:非线程安全。

  3. 数据增长分析:
    (1)Vector:缺省的情况下,增长为原数组长度的一倍。
    (2)ArrayList:自动增长原数组的50%,老容量+老容量>>1。

2. List接口和Set接口的特点?

  1. 共同特点:都继承Collection接口。
  2. List:元素是有序的,元素可以重复。因为该集合体系有索引。
    (1)ArrayList:底层数据结构使用的是顺序结构。特点:查询速度很快,但增删稍慢,线程不同步。
    (2)LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢,线程不同步。
    (3)Vector:底层是数组数据结构。特点:线程同步。被ArrayList替代了,因为效率低。
    (4)Stack:它用于模拟了“栈”这种数据结构,“栈”通常是指“后进先出”的容器。
  3. Set:元素是无序,元素不可以重复。
    (1)HashSet:实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set的迭代顺序;特别是它不保证该顺序恒久不变,此类允许使用 null元素。
    (2)TreeSet:使用元素的自然顺序对元素进行排序。
    (3)LinkedHashSet:使用链表维护了一个添加进集合中的顺序。导致当我们遍历 LinkedHashSet集合元素时,是按照添加进去的顺序遍历的。

3. 集合遍历的方式?假设顺序列表ArrayList中存储的元素是整型数字1~5,遍历每个元素,将每个元素顺序输出。

package com.briup.day11;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
/*
 * 1.遍历集合的不同方式
 */
public class ArrayListTest {
	public static void main(String[] args) {
		List<Integer> list = new ArrayList<Integer>();
		Collections.addAll(list, 1,2,3,4,5);
		//1、增强for循环
		System.out.println("增强for循环:");
		for(Integer i : list) {
			System.out.print(i);
		}
		System.out.println();
		//2、根据下标遍历
		System.out.println("根据下标遍历:");
		for(int i=0;i<list.size();i++) {
			System.out.print(list.get(i));
		}
		System.out.println();
		//3、根据迭代器遍历
		System.out.println("根据迭代器遍历:");
		Iterator<Integer> iterator = list.iterator();
		while(iterator.hasNext()) {
			Integer next = iterator.next();
			System.out.print(next);
		}
		System.out.println();
		//4、直接打印
		System.out.println("直接打印:");
		System.out.println(list);//数组的形式展示
		//5、forEach和lambda表达式
		System.out.println("lambda表达式和forEach方法:");
		System.out.println("1.直接输出:");
		list.forEach(s->System.out.print(s));
		System.out.println();
		System.out.println("2.1.通过流;"+"2.2.内部迭代:");
		Stream<Integer> stream=list.stream();
		stream.forEach((s)->{System.out.print(s);});
		System.out.println();
		System.out.println("3.stream简化:");
		list.stream().forEach(System.out::print);
	}
}

4. set集合的使用:生成10个1到20之间的不重复的随机数

public static void main(String[] args) {
	Set<Double> set = new HashSet<Double>();
	while (set.size() < 10) {
		double i = Math.random() * 20 + 1;
		set.add(i);
	}
	for (double i : set) {
		System.out.println(i);
	}
	System.out.println("容量大小为" + set.size());
}

5. list集合的使用:用一个大集合存入20个随机数字,然后筛选其中的偶数元素,放到小集合当中然后进行遍历输出。

public static void main(String[] args) {
	List<Integer> list = new ArrayList<Integer>();
	List<Integer> list2 = new ArrayList<Integer>();
	//生成随机数作为元素加入集合中
	while (list.size() < 20) {
		int random = (int) (Math.random() * 100 + 1);
		list.add(random);
	}
	//遍历大集合,筛选元素加入小集合
	for (Integer i : list) {
		if (i % 2 == 0) {
			list2.add(i);
		}
	}
	//遍历输出小集合
	for (Integer i : list2) {
		System.out.println(i);
	}
}

6. contains方法的使用:ArrayList去除集合中字符串的重复值(字符串的内容相同)。

public static void main(String[] args) {
	List<String> oldlist = new ArrayList<String>();
	Collections.addAll(oldlist, "aa", "bb", "ac", "aa", "ac");
	List<String> newlist = new ArrayList<String>();
	for (String str : oldlist) {
		if (!newlist.contains(str)) {
			newlist.add(str);
		}
	}
	for (String str : newlist) {
		System.out.println(str);
	}
}

7. retainAll和removeAll的使用:创建两个Set集合,判断这两个集合是否有交集,并打印出他们的交集。

public static void main(String[] args) {
	Set<String> s = new HashSet<String>();
	Set<String> s2 = new HashSet<String>();
	s.addAll(Arrays.asList("ab", "ac", "aa", "abb"));
	s2.addAll(Arrays.asList("abc", "ac", "aa", "ab"));
	// 保留集合中一样的,并集
	s.retainAll(s2);
	System.out.println(s);
	// 移除一样的,交集
	s2.removeAll(s);
	System.out.println(s2);
}

8. 理解排序:将1-10按照奇数在前偶数在后,奇数正序,偶数倒叙的方式保存到Set集合中。

/*
 * 思路:
 * 奇数 偶数 return -1
 * 偶数 奇数 return 1
 * 奇数 奇数 从小到大
 * 偶数 偶数 从大到小
 */
public class Test7 {
	public static void main(String[] args) {
		TreeSet<Integer> t = new TreeSet<Integer>(new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				//奇数 偶数
				if(o1%2!=0&&o2%2==0) {
					return -1;
				//偶数 奇数 
				//o1是新传进来的,不用换位置,放在o2后面就行,返回1,所以默认o1-o2=1
				}else if(o1%2==0&&o2%2!=0){
					return 1;
				//奇数 奇数 从小到大排 返回默认的就是从小到大排 
				}else if(o1%2!=0&&o2%2!=0) {
					return o1-o2;
				//偶数 偶数 从大到小排 加个负号就行
				}else if(o1%2==0&&o2%2==0) {
					return -(o1-o2);
				}
				return 0;
			}
		});
		Collections.addAll(t, 1,2,3,4,5,6,7,8,9,10);
		System.out.println(t);
	}
}

9. 重写比较器,客户排序:将学生按照成绩保存到集合中,并且名字叫tom的学生不管考多少分都位于班级的第一位。

//1.定义学生类继承比较器接口
class Student implements Comparable{
	//定义属性
	private String name;
	private int source;
	//get,set方法保证在类的外部也能获取到学生类的属性值
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getSource() {
		return source;
	}
	public void setSource(int source) {
		this.source = source;
	}
	//重写toString方法,打印学生对象时把对象属性值到打印出来
	@Override
	public String toString() {
		return "Student [name=" + name + ", source=" + source + "]";
	}
	//定义有参构造器,给学生类的属性赋值
	public Student(String name, int source) {
		super();
		this.name = name;
		this.source = source;
	}
	//定义了有参构造器会覆盖掉无参构造器,jvm不会再自动生成默认的无参构造器,所以显式定义出无参构造器
	public Student() {}
	//重写比较方法
	//学生成绩从大到小,tom排在首位
	//在比较人的时候就是这几种情况
	//1)第一个人是tom,第二个人就不是tom,就不需要交换位置(return -1)
	//2)第一个人不是tom,第二个人是tom,就需要交换位置(return 1)
	//3)两个都不是tom,就按照成绩从大到小比
	@Override
	public int compareTo(Object o) {
		if(o instanceof Student) {
			Student s1=this;
			Student s2 = (Student) o;
			//要括起来,因为有优先级
			if("tom".equals(s1.getName())&&!"tom".equals(s2.getName())) {
				return -1;
			}else if((!"tom".equals(s1.getName()))&&"tom".equals(s2.getName())) {
				return 1;
			}else {
				Integer i = s1.getSource();
				return -i.compareTo(s2.getSource());
			}
			//else{//默认从小到大 return -(s1.getSource()-s2.getSource());}
		    //else if(s1.getSource()>s2.getSource()){return -1;}
		    //else if(s1.getSource()<s2.getSource()){return 1;}
		}
		return 0;
	}
}
//2.测试排序
public class Test8{
	public static void main(String[] args) {
		TreeSet set = new TreeSet();
		Student s1 = new Student("zs", 99);
		Student s2 = new Student("tom", 60);
		Student s3 = new Student("zs1", 78);
		Student s4 = new Student("lisi", 54);
		Student s5 = new Student("zhaoliu", 83);
		set.add(s1);
		set.add(s2);
		set.add(s3);
		set.add(s4);
		set.add(s5);
		System.out.println(set);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值