泛型及其使用、Stream的方法(Java小白进阶day17)

泛型

java泛型设计原则:保证编译时不出错,运行时就不会出现ClassCastException
1、泛型类

在类上定义的泛型,在方法中也可使用

2、泛型接口

interface DemoInter<T>{
	void show(T t);
}
class Demo3Impl1 implements DemoInter<String>{
	@Override
	public void show(String t) {
		// TODO Auto-generated method stub
	}
}
class Demo3Impl2<T> implements DemoInter<T>{
	@Override
	public void show(T t) {
		// TODO Auto-generated method stub
	}	
}
public class Demo3 {
	public static void main(String[] args) {
		DemoInter<String> d1=new Demo3Impl1();
		DemoInter<String> d2=new Demo3Impl2<>();
	}
}

3、泛型方法
♥泛型方法所在类不一定是泛型类
√ 方法的返回类型前加

public static <T> void print(T[] arr){
		for(int i = 0)
		System.out.println(arr[i]);
	}

♥泛型使用必须为引用类型Integer,String,Double等
不能用8种基本数据类型

//泛型类
class TestObj<T>{
	private T data;
	private String name;
	public TestObj() {}
	public TestObj(T data, String name) {
		super();
		this.data = data;
		this.name = name;
	}
	public T getData() {
		return data;
	}
	public void setData(T data) {
		this.data = data;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "TestObj [data=" + data + ", name=" + name + "]";
	}
}

public class _demo2 {
	//输出任意数据类型的数组元素
	public static<T> void showData(T[] a) {
		for(int i = 0;i < a.length ;i++) {
			System.out.println(a[i]);
		}
		System.out.println("-------------");
		for(T t : a) {
			System.out.println(t);
		}
	}
	public static void test3() {
		Integer[] num = {1,2,3};//必须用引用类型
		showData(num);
	}
	public static void test() {
		List<Integer> list = new ArrayList<>();
		list.add(1);
		list.add(8);//确定范型后其中不可输入非下层数据类型的值
	}
	public static void test2() {
		TestObj<String> stu = new TestObj<>();
		stu.setName("zhangsna");
		stu.setData("6790");
		System.out.println(stu);
		TestObj<Float> emp = new TestObj<>();
		emp.setData(10000.34F);
		emp.setName("校长");
		System.out.println(emp);
		
	}
	public static void main(String[] args) {
		test();
	}
}

4、泛型的使用
♥<>中类型没有继承关系,本类只能用本类
♥若想使用请换为通配符?
通配符:?表示任意数据类型
5、通配符上限:<? extends Animal>
6、通配符的下限<? super Animal>

public class Demo4 {
	public static void show(List<?> list) {
		for (Object obj:list) {
			System.out.println(obj);
		}
	}
//	public static void show(List<Object> list) {
//		for (Object obj:list) {
//			System.out.println(obj);
//		}
//	}
	public static void test1(List<? extends Number> list) {
		for(Number obj:list) {
			System.out.println(obj);
		}
	}
	public static void test2(List<? super Number> list) {
		for(Object obj:list) {
			System.out.println(obj);
		}
	}
	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
//		List<Object> list = new ArrayList<>();
//		List<String> list = new ArrayList<>();
		//<>中类型没有继承关系,本类只能用本类
		//若想使用请换为通配符?
		list.add("abc");
		list.add("sdf");
		list.add("jian");
		show(list);
		List<Integer> list1 = new ArrayList<>();
		list1.add(1);
		list1.add(7);
		test1(list1);
//		test2(list1);//报错
	}
//	public <?> void t(List<?> list) {	
//	}//第一个?报错:Syntax error on token "?", Identifier expected语法错误,需要标识符
}
//class A<>{}//报错:Syntax error on token "?", Identifier expected语法错误,需要标识符

7、错误使用
1》class A<?>{}//报错:Syntax error on token “?”, Identifier expected语法错误,需要标识符
2》public <?> void t(List<?> list) {}//第一个?处报错,报错信息与上句一直
3》List<?> list = new ArrayList<?>();//第二个?处报错List<?> list = new ArrayList<>();正确

Stream

Stream:与IO流无关

1、流式思想

像生产流水线一样,一个操作接着一个操作
使流操作集合更高效

2、stream特性:

1》stream 不存储数据
2》stream不改变原数据
3》stream的延迟执行特征

3.使用Stream流的步骤:

数据源→转换成流→操作1→操作2→……

4.数据源(source):

可以是集合、数组等。

5.获取流:

// List
// 数组

6.常用方法
Stream只能被使用一次,如果还想使用,必须重新获取流。
如果不重新获取,会得到异常:
异常类型java.lang.IllegalStateException
提示消息:stream has already been operated upon or closed
1>.filter() 方法用于通过设置的条件过滤出元素
2>.map() 方法用于映射每个元素到对应的结果
3>.limit() 方法用于获取指定数量的流
4>.跳过前n个stream.skip()
5>.流的连接Stream.concat(stream1,stream2)
6>.回数量count()
7>.可以把流转换为 List 类型:collect(Collectors.toList());
8>.求和的方法reduce(0, (x, y) -> x + y)或者reduce(1,(x,y)->x*y)
9>.去重distinct()
10>.排序:sorted()
11>forEach()终结方法

public class Demo5 {
	public static void test1() {
		List<String> listStr =  new ArrayList<>();
		listStr.add("hello");
		listStr.add("admin");
		Integer[] num = {1,2,3,4};
		Stream<String> streamStr = listStr.stream();
		Stream<Integer> streamInt = Stream.of(num);
		Stream.concat(streamStr,streamInt).forEach(e->System.out.println(e));
		//concat连接两个流
//		streamInt.forEach(e->System.out.println(e));
		//streamInt.forEach(e->System.out.println(e));
		//终结性方法(返回类型不是流),不可多次使用流运行出现java.lang.IllegalStateException
	}
	public static void test2() {
		Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9);
//		Stream<Integer> numStream = stream.filter(e -> e%2!=0);
//		numStream.forEach(e->System.out.println(e));
		Stream<Integer> numStream = stream.filter(e ->{ 
			System.out.println("------------");
			return e%2!=0;
			});
		System.out.println("------------8-------");
		numStream.forEach(e->System.out.println(e));//延迟执行
		
		stream = Stream.of(1,2,3,4);
		stream.map(e->e*e).forEach(e->System.out.println(e));
		
		stream = Stream.of(1,2,3,4);
		stream.limit(3).forEach(e->System.out.println(e));//限制输出3个
		stream = Stream.of(1,2,3,4);
		stream.skip(3).forEach(e->System.out.println(e));//跳过3个
		
		
	}
	public static void test3() {
		Stream<Integer> stream = Stream.of(1,2,3,4);
		System.out.println(stream.count());
		
		//返回一个集合
		stream = Stream.of(1,2,3,4);
		List<Integer> list = stream.collect(Collectors.toList());
		System.out.println(list);
		
		stream = Stream.of(1,2,3,4);
		System.out.println(stream.reduce(0,(x,y)->x+y));
		
		stream = Stream.of(1,2,3,4,1,4,3);
		stream.distinct().forEach(e->System.out.println(e));
		
		System.out.println("---------排序--------------");
		stream = Stream.of(1,2,3,4,1,4,3);
		stream.sorted().forEach(e->System.out.print(e+"   "));
//		stream.sorted((x,y)->y-x).forEach(e->System.out.print(e+"   "));//从大到小,自己重写compareTo方法
		
	}
	public static void main(String[] args) {
		
		test2();
	}
}

下面有一组练习题以及答案
练习:
1.//有如下整数1,-2,-3,4,-5,使用Stream取元素绝对值并打印
2.给定一个数字列表,如何返回一个由每个数的平方构成的列表,给定【1,2,3,4,5】, 应该返回【1,4,9,16,25】。
3.有如下7个元素黄药师,冯蘅,郭靖,黄蓉,郭芙,郭襄,郭破虏,使用Stream将以郭字开头的元素存入新集合
4.已知ArrayList集合中有如下元素{陈玄风、梅超风、陆乘风、曲灵风、武眠风、冯默风、罗玉风},
使用Stream
《1、取出前2个元素并在控制台打印输出。
《2、取出后2个元素并在控制台打印输出。
5.怎样用 map 和 reduce 方法数一数流中有多少个Employee
List emps = Arrays.asList(
new Employee(102, “李四”, 59),
new Employee(101, “张三”, 18),
new Employee(103, “王五”, 28),
new Employee(104, “赵六”, 8),
new Employee(105, “田七”, 38)
);
6.找出2011年发生的所有交易, 并按交易额排序(从低到高)
class Transaction {
private int year; //交易时间
private int value; //交易额
方法。。。。
List transactions =Arrays.asList(
new Transaction(2011, 300),
new Transaction(2012, 1000),
new Transaction(2011, 400),
new Transaction(2012, 710),
new Transaction(2011, 200),
new Transaction(2012, 700),
new Transaction(2012, 950)
);
答案:

public class Demo6test {
	//1\有如下整数1,-2,-3,4,-5,使用Stream取元素绝对值并打印
	public static void test1() {
		Stream<Integer> stream = Stream.of(1,-2,-3,4,-5);
//		stream.sorted((x,y)->Math.abs(x)-Math.abs(y)).forEach(e->System.out.println(Math.abs(e)));
//		stream.forEach(e->System.out.println(Math.abs(e)));
		stream.map(e->Math.abs(e)).forEach(e->System.out.println(e));
	}
	
	//2\给定一个数字列表,如何返回一个由每个数的平方构成的列表
	public  static void test2() {
		Stream<Integer> stream = Stream.of(1,2,3,4,5);
//		stream.forEach(e->System.out.println(e*e));
		stream.map(e->e*e).forEach(System.out::println);
	}
	
	//3.有如下7个元素黄药师,冯蘅,郭靖,黄蓉,郭芙,郭襄,郭破虏,使用Stream将以郭字开头的元素存入新集合
	public static void test3() {
		Stream<String> stream = Stream.of("黄药师","冯蘅","郭靖","黄蓉","郭芙","郭襄","郭破虏","hajn郭7");

> 这里是引用

//		stream.filter(e->e.startsWith("郭")).forEach(e->System.out.println(e));
		System.out.println(stream.filter(e->e.startsWith("郭")).collect(Collectors.toList()));//filter可以将所有返回()内true的收集起来返回一个stream
	}
	

	//4.已知ArrayList集合中有如下元素{陈玄风、梅超风、陆乘风、曲灵风、武眠风、冯默风、罗玉风},
	public static void test4() {
		List<String> list = new ArrayList<>();
		list.add("陈玄风");
		list.add("梅超风");
		list.add("陆乘风");
		list.add("曲灵风");
		list.add("武眠风");
		list.add("冯默风");
		list.add("罗玉凤");
		Stream<String> stream = list.stream();
		stream.limit(2).forEach(e->System.out.println(e));
		stream = list.stream();
//		stream.skip(5).forEach(e->System.out.println(e));
		stream.skip(list.size()-2).forEach(e->System.out.println(e));
	}
	
	//5.怎样用 map 和 reduce 方法数一数流中有多少个Employee
	public static void test5() {
		List<Employee> emps = Arrays.asList(
				new Employee(101, "张三", 18),
				new Employee(102, "李四", 59),
				new Employee(103, "王五", 28),
				new Employee(104, "赵六", 8),
				new Employee(105, "田七", 38)
				);
		Stream<Employee> emp =emps.stream();
//		System.out.println(emp.count());
		System.out.println(emp.map(e->1).reduce(0,(x,y)->x+y));
	}
	
	//6.找出2011年发生的所有交易, 并按交易额排序(从低到高)
	public static void test6() {
		List<Transaction> transaction = Arrays.asList(
				new Transaction(2011,300),
				new Transaction(2012,1000),
				new Transaction(2011,400),
				new Transaction(2012,7100),
				new Transaction(2011,200),
				new Transaction(2012,700),
				new Transaction(2012,950)
				);
		Stream<Transaction> trans = transaction.stream();
		trans.filter(e->
			e.getYear()==2011
		).sorted((t1,t2)->t1.getValue()-t2.getValue()).forEach(System.out::println);
	}
	public static void main(String[] args) {
		test3();
	}
}
public class Employee {
	private int id;
	private String name;
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	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;
	}
	public Employee(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
}

public class Transaction {
	private int year;
	private int value;
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	@Override
	public String toString() {
		return "Transaction [year=" + year + ", value=" + value + "]";
	}
	public Transaction(int year, int value) {
		super();
		this.year = year;
		this.value = value;
	}
	
}


List、Set、Map、LinkList

1、List集合的实现类
LinkedList和Vector
LinkedList和ArrayList都是线程不安全的的
Vector是线程安全的

2、Set集合
不重复:先判断hashCode();相同,还有判断equals()方法,只有返回true才表示同一对象
HashSet和TreeSet
HashSet基于HashMap的实现,HashSet的元素是map中的key。
TreeSet的元素必须是有排序规则的对象,否则会运行时异常

public class Demo7 {
	public static void test(){
		Set<String> set = 
				new HashSet<>();
		set.add("张三");
		set.add("张三");
		set.add("李四");
		set.add("王五");
		set.remove("王五");
		set.forEach(System.out::println);
	}
	public static void test2() {
		Set<Emp> set = new HashSet<>();
		set.add(new Emp("张三"));
		set.add(new Emp("李四"));
		set.add(new Emp("张三"));
		set.add(new Emp("王五"));
		set.forEach(System.out::println);
		//若Emp不重写hashCode(),equals(Object obj)方法,会出现重复值,有多个张三
	}
	public static void main(String[] args) {
		test2(); 
	}
}
public class Emp{
	private String id;
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Emp other = (Emp) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	private String name;
	public Emp(){
		
	}
	public Emp(String name) {
		this.setName(name);
		
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "Emp [name=" + name + "]";
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	
}

3、Map集合
HashMap
Map
k-v
HashMap与HashTable区别
1>HashTable线程安全
2>HashMap的key/value可为null,
HashTable键值都不可以为null,会出现空指针异常

package Demo0807;

import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Demo1 {
	public static void main(String[] args) {
		Map<String, Object> map = new Hashtable<>();
		map.put("k","njn");
		test3();

	}
	public static void test1() {
		Map<String, Object> map = new HashMap<>();
		// 添加元素
		map.put("a", 97);
		map.put("b", 98);
		map.put("b", 998);// key值相同,修改了value
		map.put("c", 99);
		map.remove("c");
		System.out.println(map.get("a"));
		System.out.println(map.get("b"));
		System.out.println(map.get("c"));// 获取已删除或不存在键值对,返回为null
	}
	public static void test2() {
		Map<String, Object> stu = new HashMap<>();
		stu.put("id","200090001");
		stu.put("name", "admin");
		stu.put("phone", "1234544");
		stu.put("age", 18);
		stu.put("adress","光谷软件园");
		System.out.println(stu.containsKey("name"));
		System.out.println(stu.containsValue("admin"));
	}
	public static void test3() {
		Map<String, Object> stu = new HashMap<>();
		stu.put("id","200090001");
		stu.put("name", "admin");
		stu.put("phone", "1234544");
		stu.put("age", 18);
		stu.put("adress","光谷软件园");
		//遍历方式一
		System.out.println("-----------1----------");
		Set<String> key = stu.keySet();
		for (String key1:key) {
			System.out.println(key1+":"+stu.get(key1));
		}
		//第二种
		System.out.println("-------------2-----------");
		Set<Entry<String, Object>> stua = stu.entrySet();
		for(Entry<String, Object> entry : stua) {
			System.out.println(entry.getKey()+":"+entry.getValue());
		}
		//第三种
		System.out.println("-----------3------------");
		stu.forEach((k,v)->System.out.println(k+":"+v));
		System.out.println("-----------value-----------");
		System.out.println(stu.values());
		Collection<Object> collection = stu.values();
		for(Object obj : collection) {
			System.out.println(obj);
		}
	}
	
}

练习:接受键盘输入一个字符串,统计字符的个数 vserererew

public class Demo2test {
	public static void main(String[] args) {
		System.out.println("请输入一个字符串");
		Scanner sc = new Scanner(System.in);
		String str = sc.next();
		Map<Character, Integer> map = new HashMap<>();
//		char[] array =  str.toCharArray();
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if(map.containsKey(c)) {
				int count = map.get(c);
				map.put(c,++count);
			}else {
				map.put(c,1);
			}
		}
		map.forEach((k,v)->System.out.println(k+":"+v));
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值