黑马程序员--Java学习17--集合框架

本文深入讲解Java集合框架,包括Collection接口及其子接口List和Set,Map接口及其具体实现类如HashMap和TreeMap的使用方法。并通过多个实例演示如何操作这些集合。

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

一、集合框架         

          Java中的集合框架提供了一套设计优良的接口和类,成为集合API,它使程序员操作成批的数据或者对象元素极为方便,尤其是当用户事先不知道要存放数据的个数,或者需要一种比数组下标存取机制更灵活的方法时,就需要用到集合类。集合框架是程序开发过程中极其重要的一个概念,几乎每个项目都需要使用集合框架,熟练掌握其中的类和接口的使用方法可以大大提供程序开发的效率。集合框架结构结构由两颗接口树构成:第一棵树根节点为Collection接口,它定义了所有集合的基本操作,如添加,删除,遍历等。它的子接口Set、List等则提供了更加特殊的功能。第二棵树根节点为Map接口,和哈希表类似,保持的是键值对的集合,可以通过键来实现对值元素的快速访问。集合框架如下图示:


下面我将对集合框架中的接口和类进行详细的介绍。

二、Collection接口

        Collection定义了所有属于集合的类都应该具有的通用方法,如下:

  • boolean   add(Object o)                           插入单个对象,插入成功返回true,否则返回false
  • boolean   addAll(Collection c)                 添加另外一个集合对象c中的所有对象,插入成功返回true,否则返回false
  • Object[]   toArray()                                   以数组的形式返回内容
  • Object[]   toArray()                                   以数组的形式返回内容,参数数组的类型就是所希望返回的类型
  • Iterator    iterator()                                    返回一个实现了Iterator接口的对象
  • void         clear()                                       清空所有对象
  • boolean   remove(Object o)                     删除指定的对象,删除成功返回true,否则返回false
  • boolean   removeAll(Collection c)            删除c中所拥有的对象,删除成功返回true,否则返回false
  • boolean   retainAll(Collection c)               保留指定的对象,成功返回true,否则将返回false
  • boolean   contains(Object o)                    检查是否包含指定的对象
  • boolean   containsAll(Collecion c)            检查是否包含c中所包含的对象
  • boolean   isEmpty()                                  判断集合是否为空
  • int            size()                                        获取集合中的对象个数

       2.1 List接口

       List:元素是有序的,元素可以重复,因为该集合体系有索引

       List接口实现了三个子类:

       ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快。但是增删速度慢,线程不同步
       LinkedList: 底层使用的链表数据结构。增删速度快,查询速度慢
       Vector:底层是数组数据结构,线程同步,被ArrayList替换了。

重要的是ArrayList和LinkedList,Vector已经被ArrayList取代了。

List接口在Collection接口的基础上有增加了一些特有方法,凡是可以操作角标的方法都是该体系特有的方法


 add(index,eldment);
 addAll(index,Collection);


 remove(index);


 set(index,element);


 get(index);
 subList(from,to);
 listIterator();

对于List的方法操作示例如下:

public static void method() {
	ArrayList a1=new ArrayList();
	
	//1.添加元素。
	a1.add("java01");
	a1.add("java01");
	a1.add("java03");
	a1.add("java04");

	//在指定位置添加元素
	a1.add(1,"java09");

	//删除指定位置的元素
	a1.remove(2);

	//修改元素
	a1.set(2,"java007");


	//查找,通过角标获取元素
	a1.get(1);

	//获取所有元素
	for (int x=0;x<a1.size() ;x++ ) {
		sop(a1.get(x));
	}

	//通过迭代器获取
	Iterator it=a1.iterator();
	while (it.hasNext()) {
		sop(it.next());
	}

	//通过indexOf获取对象的位置
	sop(a1.indexOf("java09"));
	
	//获取子集
	List sub=a1.subList(1,3);


}

    来看一个ArrayList的例子:

例1:

/*
去除ArrayList中的重复元素
*/
import java.util.*;
class  ArrayListTest {

	public static void sop(Object obj) {

		System.out.println(obj);
	}
	public static void main(String[] args) {
		
		ArrayList a1=new ArrayList();
		a1.add("java01");
		a1.add("java02");
		a1.add("java01");
		a1.add("java03");
		a1.add("java04");

		sop(a1);

		a1=singleElements(a1);
		sop(a1);
	}
	public static ArrayList singleElements(ArrayList list) {
		
		ArrayList newList= new ArrayList();
		 Iterator it =list.iterator();
		 while (it.hasNext()) {
			 Object obj=it.next();
			 if (!newList.contains(obj)) {
				 newList.add(obj);
			 }
		 } 
		 return newList;
	}
}

例2:

 将自定义对象作为元素存到ArrayList集合中,并去除重复元素

比如:存入对象 ,同姓名同年龄的,视为同一个人,为重复元素

/*
思路:
1、对人的描述,将数据封装进对象
2、定义容器,将人进行存储
3、取出


List集合判断元素是否相同,根据元素的equals方法
*/
import java.util.*;
class Person {
	private String name;
	private int age;
	Person(String name,int age) {
		this.name=name;
		this.age=age;

	}	
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public boolean equals(Object obj) {//List集合判断元素是否相同,根据元素的equals方法,为什么不复写contains方法
		if(!(obj instanceof Person)) {
			return false;
		}
		
		Person p =(Person)obj;
		return (this.name.equals(p.name))&&(this.age==p.age);
		
	}
}
class  ArrayListTest2{
	public static void sop(Object obj) {
		System.out.println(obj);
	}
	public static void main(String[] args) {
		ArrayList a1=new ArrayList();
		a1.add(new Person("lisi01",30));//Object obj;obj=Person();//多态
		a1.add(new Person("lisi02",31));
		a1.add(new Person("lisi03",32));
		a1.add(new Person("lisi03",32));
		a1.add(new Person("lisi04",33));
		a1.add(new Person("lisi05",34));
		a1.add(new Person("lisi05",34));


		a1=singleElements(a1);
		//sop(a1);

		sop(a1.remove(new Person("lisi01",30)));//remove调用的也是底层的equals
		
		Iterator it=a1.iterator();
		
		while (it.hasNext()) {

			Person p=(Person)it.next();//向下转型
			sop(p.getName()+"..."+p.getAge());
		}
		
	}
	public static ArrayList singleElements(ArrayList list) {
		
		ArrayList newList= new ArrayList();
		 Iterator it =list.iterator();
		 while (it.hasNext()) {
			 Object obj=it.next();
			// Person p=(Person)it.next();
			 if (!newList.contains(obj)) {
				 newList.add(obj);
			 }
		 } 
		 return newList;
	}
}


        在这里需强调一下:List集合判断元素是否相同依靠的是equals()方法;如果要自定义比较方式,需让待存元素具有排序方式,就需要复写equals()方法。


 LinkedList: 底层使用的链表数据结构。增删速度快,查询速度慢

       LinkedList:特有方法:

              addFirst();//头插
              addLast();//尾插

              removeFirst();
              removeLast();
              获取元素后元素被删除


     如果链表中没有元素,那么抛出NoSuchElementException异常
     但是升级后 返回null

     JDK1.6出现了替代方法

             offerFirst();
             offerLast();
             添加元素

             peerFirst();
             peerLast();
             获取元素,没有元素,返回null

             pollFirst();
             pollLast();
             获取元素后元素被删除,没有元素,返回null

例:

        使用LinkedList模拟一个堆栈或者队列数据结构。

       堆栈:先进后出  First In Last Out 如同一个杯子

       队列:先进先出 Fisst In First Out 如同一个杯子

import java.util.*;
class MyQueue {
	private LinkedList link;
	MyQueue() {
		link=new LinkedList();
	}
	public void myAdd(Object obj) {
		link.addFirst(obj);
		
	}
	public Object myGet() {
		return link.removeLast();
	}
	public boolean myIsNull() {
		return link.isEmpty();
	}

}
class LinkedListTest {
	public static void main(String[] args) {

		MyQueue q=MyQueue();
		q.myAdd("java01");
		q.myAdd("java02");
		q.myAdd("java03");
		q.myAdd("java04");
		
		while (!q.myIsNull) {
		
			System.out.println(q.myGet());

		}
	}
}


       2.2   Set集合

Set集合的特点是:元素是无序的,元素不可以重复,而且Set集合的方法和Collection保持一致

Set接口下有两个子类:

HashSet和TreeSet

HashSet: 底层数据结构是哈希表
       HashSet是如何保证元素唯一性的呢?
       是通过元素的两个方法,hashCode和equals来完成的,如果元素的HashCode值相同,才会判断equals是否相同如果元素的HashCode值不相同,不会调用equals

例:

import java.util.*;
class Person {
	private String name;
	private int age;
	Person(String name,int age) {
		this.name=name;
		this.age=age;

	}	

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	public int hashCode() {

		System.out.println("name="+this.name+"..hashCode="+name.hashCode());//显示过程
		return name.hashCode()+age;
	}

	public boolean equals(Object obj) {
		if(!(obj instanceof Person)) {
			return false;
		}
		Person p =(Person)obj;
		System.out.println(this.name+"...."+p.name);
		return (this.name.equals(p.name))&&(this.age==p.age);
		
	}
}
class  HashSetDemo {
	public static void sop(Object obj) {
		System.out.println(obj);
	}
	public static void main(String[] args) {
		HashSet a1=new HashSet();
		a1.add(new Person("lisi01",30));//Object obj;obj=Person();//多态
		a1.add(new Person("lisi02",31));
		a1.add(new Person("lisi03",32));
		a1.add(new Person("lisi03",32));
		a1.add(new Person("lisi04",33));
		a1.add(new Person("lisi05",34));
		a1.add(new Person("lisi05",34));

		sop(a1.contains(new Person("lisi06",35)));
		Iterator it=a1.iterator();
		
		while (it.hasNext()) {

			Person p=(Person)it.next();//向下转型
			sop(p.getName()+"..."+p.getAge());
		}
		
	}
}

TreeSet:可以对Set集合中的元素进行自然排序,底层数据结构是二叉树
      保证元素唯一性的依据:compareTo方法return 0;

     TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也称为元素的自然排序,或者叫做默认顺序。

例:

需求:往Set集合中存储自定义对象学生,按照年龄进行排序

import java.util.*;
class Student implements Comparable{
	private String name;
	private int age;
	Student(String name,int age) {
		this.name=name;
		this.age=age;

	}	

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
	/**/
	public int hashCode() {

		System.out.println("name="+this.name+"..hashCode="+name.hashCode());//显示过程
		return name.hashCode()+age;
	}
	
	public int compareTo(Object obj) {

		/*
		return 1;//怎么存进去的怎么取出来
		*/
		if(!(obj instanceof Student)) {
			throw new RuntimeException("不是学生对象");
		}
		Student stu =(Student)obj;
		System.out.println(this.age+"...."+stu.age);
		if (this.age>stu.age) {
			return 1;
		}
		if (this.age==stu.age) {
			return this.name.compareTo(stu.name);
		}
		return -1;	
	}
}
class  TreeSetDemo {
	public static void sop(Object obj) {
		System.out.println(obj);
	}
	public static void main(String[] args) {

		TreeSet a1=new TreeSet();
		a1.add(new Student("lisi01",30));//Object obj;obj=Student();//多态
		a1.add(new Student("lisi02",31));
		a1.add(new Student("lisi03",32));
		a1.add(new Student("lisi03",32));
		a1.add(new Student("aisi04",33));
		a1.add(new Student("lisi05",34));
		a1.add(new Student("risi05",34));

		//sop(a1.contains(new Student("lisi06",35)));
		Iterator it=a1.iterator();
		
		while (it.hasNext()) {

			Student p=(Student)it.next();//向下转型
			sop(p.getName()+"..."+p.getAge());
		}
	}
}


     TreeSet的第二种排序方式
     当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式:构造函数

例:自定义比较器,按照名字排序

import java.util.*;
class TreeSetDemo2 {
	public static void sop(Object obj) {
		System.out.println(obj);
	}
	public static void main(String[] args) {

		TreeSet a1=new TreeSet(new MyCompare());//使用自定义的比较器

		a1.add(new Student("lisi01",30));
		a1.add(new Student("lisi02",31));
		a1.add(new Student("lisi03",32));
		a1.add(new Student("lisi03",32));
		a1.add(new Student("aisi04",33));
		a1.add(new Student("lisi05",34));
		a1.add(new Student("risi05",34));

		
		Iterator it=a1.iterator();
		
		while (it.hasNext()) {

			Student p=(Student)it.next();//向下转型
			sop(p.getName()+"..."+p.getAge());
		}
	}
}
class Student implements Comparable{
	private String name;
	private int age;
	Student(String name,int age) {
		this.name=name;
		this.age=age;

	}	

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	public int hashCode() {

		System.out.println("name="+this.name+"..hashCode="+name.hashCode());//显示过程
		return name.hashCode()+age;
	}

	public int compareTo(Object obj) {

		return 1;//怎么存进去的怎么取出来
		/*
		if(!(obj instanceof Student)) {
			throw new RuntimeException("不是学生对象");
		}
		Student stu =(Student)obj;
		System.out.println(this.age+"...."+stu.age);
		if (this.age>stu.age) {
			return 1;
		}
		if (this.age==stu.age) {
			return this.name.compareTo(stu.name);
		}
		return -1;	*/
	}
}
class MyCompare implements Comparator {//自定义比较器

	public int compare(Object o1,Object o2) {
		Student s1=(Student)o1;
		Student s2=(Student)o2;
		int num =s1.getName().compareTo(s2.getName());
		if (num==0) {

			return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
			/*
			if (num==0) {
				if (s1.getAge()>s2.getAge()) {
					return 1;
				}
				if (s1.getAge()==s2.getAge()) {
					return 0;
				}
				return -1;
			}
		}*/
		
		}
		return num;
	}
}

三、Map

       Map集合:该集合存储键值对。一对一对的往里存,而且要保证键的唯一性。

Map
 |--Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的。jdk1.0,效率低
 |--HashMap:底层是哈希表数据结构,允许使用null键null值,该集合是不同步的,jdk1.2,效率高
 |--TreeMap:底层是二叉树数据结构,线程不同步,可以用Map集合中的键进行排序

重点是HashMap和TreeMap。


关于Map集合的操作有:

1,添加
   V put(K key, V value) 
  void putAll(Map<? extends K,? extends V> m) 

 

 2,删除
   void clear()
    V remove(Object key) 
  


 3,判断
  boolean containsKey(Object key)
  boolean containsValue(Object value)
  boolean isEmpty() 


 
 4,获取
  int size()
  V get(Object key)
  Collection<V> values()
  

  Set<Map.Entry<K,V>> entrySet()
  Set<K> keySet() 

常用方法操作演示:

import java.util.*;
class MapDemo01 {
	public static void main(String[] args) {
		
		Map<String,String> map=new HashMap<String,String>();
		
		//put也是有返回值的,返回的对应键的值,
		//添加元素时,如果出现添加相同的键,那么后添加的值覆盖原有键对应的值。
		System.out.println("put:"+map.put("01","zhangshan01"));
		System.out.println("put:"+map.put("01","wangwu01"));
		map.put("02","zhangshan02");
		map.put("03","zhangshan03");

		System.out.println("containsKey:"+map.containsKey("02"));
		
		//获取map集合中所有的值
		Collection<String> coll=map.values();

		System.out.println(coll);
		System.out.println(map);
	}
}


需要重点掌握的是后两种方法,前面的一些方法都是基础操作。

map集合的两种取出方式;
     1、Set<k> keySet(): 将Map中所有的键存入到Set集合,因为Set具备迭代器。所有可以迭代方式取出所有的键,再根据get方法,获取每一个键对应的值。

例:

import java.util.*;
class MapDemo02 {
	public static void main(String[] args) {

		Map<String,String> map=new HashMap<String,String>();

		map.put("02","zhangshan02");
		map.put("03","zhangshan03");
		map.put("01","zhangshan01");
		map.put("04","zhangshan04");


		//先获取Map集合的所有键Set集合,keySet();
		Set<String> keySet=map.keySet();
		
		//有了Set集合就可以获取迭代器
		Iterator<String> it=keySet.iterator();

		while (it.hasNext()) {
			String key=it.next();
			System.out.println("key:"+key+"...value:"+map.get(key));//通过Map中的get(key);获取value
		}
	}
}
  
     2、Set<Map.Entry<K,V>> entrySet() :将Map集合中的映射关系存入到了Set集合中,而这个关系的数据类型就是:Map.Entry

import java.util.*;
class MapDemo02 {
	public static void main(String[] args) {

		Map<String,String> map=new HashMap<String,String>();

		map.put("02","zhangshan02");
		map.put("03","zhangshan03");
		map.put("01","zhangshan01");
		map.put("04","zhangshan04");


		//将Map集合中的映射关系取出 ,存入到Set集合中
		Set<Map.Entry<String,String>> entruSet=map.entrySet();

		Iterator<Map.Entry<String,String>> it=entry.itetator();

		while (it.hasNext()) {

			Map.Entry<String,String> me=it.next();
			String key=me.getKey();
			String value=me.getValue();
			System.out.println(key+".."+value);
		}
	}
}


下面看几道例题:

例1:

/*
每一个学生都有对应的归属地。
学生Student, 地址String
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。

解题思路:
1、描述学生。

2、定义Map容器,将学生作为键,地址作为值,存入。

3、获取Map集合中的元素。

*/
import java.util.*;
class Student implements Comparable<Student> {
	private String name;
	private int age;
	Student(String name,int age) {
		this.name=name;
		this.age=age;
		
	}
	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
	
	public int compareTo(Student s) {

		int num=new Integer(this.age).compareTo(new Integer(s.age));
		
		if (num==0) {
			return this.name.compareTo(s.name);
		}	
		return num;
	}

	public int hashCOde() {
		return name.hashCode()+age*21;
	}

	public boolean equals(Object obj) {
		if (!(obj instanceof Student)) {
			throw new ClassCastException("类型不匹配");
		}
		 Student s=(Student)obj;
		 return this.name.equals(s.name) && this.age==s.age;
		
	}

	public String toString() {
		return name+"年龄"+age;
	}
}

class MapTest03 {
	public static void main(String[] args) {

		HashMap<Student,String> map=new HashMap<Student,String>();

		map.put(new Student("lisi1",21),"北京");
		map.put(new Student("lisi2",22),"天津");
		map.put(new Student("lisi3",23),"南京");
		map.put(new Student("lisi4",24),"上海");

		//第一种取出方式
		Set<Student> s=map.keySet();

		Iterator<Student> it=s.iterator();
		while (it.hasNext()) {
			Student key=it.next();
			String add=map.get(key);
			System.out.println(key+".."+add);

		}
		//第二种取出方式
		Set<Map.Entry<Student,String>> ss=map.entrySet();

		Iterator<Map.Entry<Student,String>> itor=ss.iterator();

		while (itor.hasNext()) {
			Map.Entry<Student,String> stuAdd=itor.next();
			Student key=stuAdd.getKey();
			String add_=stuAdd.getValue();
			System.out.println(key+"....."+add_);

		}
		


		
	}
}

例2:

/*
需求:对学生对象的年龄进行升序排序。

因为数据时一键值对形式存在的,
所以要使用可以排序的Map集合。TreeMap

*/
import java.util.*;
class Student implements Comparable<Student> {
	private String name;
	private int age;
	Student(String name,int age) {
		this.name=name;
		this.age=age;
		
	}
	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
	
	public int compareTo(Student s) {//按年龄排

		int num=new Integer(this.age).compareTo(new Integer(s.age));
		
		if (num==0) {
			return this.name.compareTo(s.name);
		}	
		return num;
	}

	public int hashCOde() {
		return name.hashCode()+age*21;
	}

	public boolean equals(Object obj) {
		if (!(obj instanceof Student)) {
			throw new ClassCastException("类型不匹配");
		}
		 Student s=(Student)obj;
		 return this.name.equals(s.name) && this.age==s.age;
		
	}

	public String toString() {
		return name+"年龄"+age;
	}
}

//自定义比较器,按姓名排
class StuNameComparator implements Comparator<Student> {

	public int compare(Student s1,Student s2) {
		int num=s1.getName().compareTo(s2.getName());
		if (num==0) {
			return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}
		return num;
		
	}
}
class MapTest04 {
	public static void main(String[] args) {
		
		TreeMap<Student,String> map=new TreeMap<Student,String>(new StuNameComparator());
		map.put(new Student("lisi1",25),"北京");
		map.put(new Student("lisi2",22),"天津");
		map.put(new Student("lisi3",23),"南京");
		map.put(new Student("lisi4",24),"上海");
	
		Set<Map.Entry<Student,String>> ss=map.entrySet();

		Iterator<Map.Entry<Student,String>> itor=ss.iterator();

		while (itor.hasNext()) {
			Map.Entry<Student,String> stuAdd=itor.next();
			Student key=stuAdd.getKey();
			String add_=stuAdd.getValue();
			System.out.println(key+"....."+add_);

		}
	}
}

例3:

/*
练习:获取该字符串“ajlkgijoikghgafgash”中字母出现的次数
*/
import java.util.*;
class TreeMapDemo05 {
	public static void main(String[] args) {
		
		String s=getCount("alkjfognskadkfalkd");
		System.out.println(s);
	}
	public static String getCount(String str) {
		
		char[] ch=str.toCharArray();
		
		TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>();
		for (int i=0;i<ch.length ;i++ ) {
			
			if (!(ch[i]>='a'&&ch[i]<='z'||ch[i]>='A'&&ch[i]<='Z')) {
				continue;
			}
			Integer value= tm.get(ch[i]);
			if (value==null) {
				tm.put(ch[i],1);
			}
			else {
				tm.put(ch[i],value+1);
			}
		}
		
		StringBuffer sb=new StringBuffer();

		Set<Map.Entry<Character,Integer>> entry=tm.entrySet();

		Iterator<Map.Entry<Character,Integer>> it=entry.iterator();

		while (it.hasNext()) {

			Map.Entry<Character,Integer> t=it.next();
			char key=t.getKey();
			int value=t.getValue();
			sb.append(key+"("+value+")");
		}

		return sb.toString();
	}
}



---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------











下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
源码来自:https://pan.quark.cn/s/a4b39357ea24 在VC++开发过程中,对话框(CDialog)作为典型的用户界面组件,承担着与用户进行信息交互的重要角色。 在VS2008SP1的开发环境中,常常需要满足为对话框配置个性化背景图片的需求,以此来优化用户的操作体验。 本案例将系统性地阐述在CDialog框架下如何达成这一功能。 首先,需要在资源设计工具中构建一个新的对话框资源。 具体操作是在Visual Studio平台中,进入资源视图(Resource View)界面,定位到对话框(Dialog)分支,通过右键选择“插入对话框”(Insert Dialog)选项。 完成对话框内控件的布局设计后,对对话框资源进行保存。 随后,将着手进行背景图片的载入工作。 通常有两种主要的技术路径:1. **运用位图控件(CStatic)**:在对话框界面中嵌入一个CStatic控件,并将其属性设置为BST_OWNERDRAW,从而具备自主控制绘制过程的权限。 在对话框的类定义中,需要重写OnPaint()函数,负责调用图片资源并借助CDC对象将其渲染到对话框表面。 此外,必须合理处理WM_CTLCOLORSTATIC消息,确保背景图片的展示不会受到其他界面元素的干扰。 ```cppvoid CMyDialog::OnPaint(){ CPaintDC dc(this); // 生成设备上下文对象 CBitmap bitmap; bitmap.LoadBitmap(IDC_BITMAP_BACKGROUND); // 获取背景图片资源 CDC memDC; memDC.CreateCompatibleDC(&dc); CBitmap* pOldBitmap = m...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值