黑马程序员——集合框架-程序员宅基地

技术标签: java  黑马程序员  

------- android培训java培训、期待与您交流! ----------

集合框架


一、概述

集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。

  • 接口:是代表集合的抽象数据类型。接口允许集合独立操纵其代表的细节。在面向对象的语言,接口通常形成一个层次。
  • 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构。
  • 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。

Java集合框架:

1. 什么是框架:类库的集合

2. 集合框架:用来表示和操作的统一的框架,包含了实现集合的接口与类

3. 集合:存放数据的容器。集合框架包含了两部分:一部分是接口,一部分是类

4. 为什么会出现接口:因为集合框架中的很多类,功能是相似的,所以用接口来规范类。


主要结构图:



注:1. 在集合框架中,接口Map和Collection在层次结构上没有任何亲缘关系,它们是截然不同的。

        2. 不要简单的认为集合类就这些,jdk中集合类有很多这些是我们经常用到的而已,Collection、List、Set、Queue和Map都是接口(Interface),不是具体的类实现。


为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

 

数组和集合类同是容器,有何不同?

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。

数组中可以存储基本数据类型,集合只能存储对象。

 

集合类的特点:

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

 

为什么会出现这么多的容器呢?

因为每一个容器对数据的存储方式都有不同,这个存储方式称之为:数据结构。



二、共性方法

1,add方法的参数类型是Object。以便于接收任意类型对象。

2,集合中存储的都是对象的引用(地址)。



三、迭代器

什么是迭代器呢?

其实就是集合的取出元素的方式。

  就把取出方式定义在集合的内部。这样取出方式就可以直接访问集合内部的元素。那么取出方式就被定义成了内部类。

而每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都有共性内容:判断和取出。那么可以将这些共性抽取。

那么这些内部类都符合一个规则,该规则是Iterator。


如何获取集合的取出对象呢?

通过一个对外提供的方法。iterator();

格式:

                ArrayList al = new ArrayList();

		//1.添加元素。
		al.add("java01");
		al.add("java02");
		
                Iterator it = al.iterator(); //获取迭代器,用于取出集合中的元素。
		while (it.hasNext())
		{
			System.out.println(it.next());
		}


例如:

import java.util.*;

class CollectionDemo 
{
	public static void main(String[] args) 
	{
		//method_2();
		method_get();
	}

	public static void method_get()
	{
		ArrayList al = new ArrayList();

		//1.添加元素。
		al.add("java01");
		al.add("java02");
		al.add("java03");
		al.add("java04");

		/*
		Iterator it = al.iterator(); //获取迭代器,用于取出集合中的元素。
		while (it.hasNext())
		{
			sop(it.next());
		}
		*/
		
		for (Iterator it=al.iterator(); it.hasNext(); )
		{
			sop(it.next());
		}
	}

	public static void method_2()
	{
		ArrayList al1 = new ArrayList();
		al1.add("java01");
		al1.add("java02");
		al1.add("java03");
		al1.add("java04");

		ArrayList al2 = new ArrayList();
		al2.add("java03");
		al2.add("java04");
		al2.add("java05");
		al2.add("java06");

		//al1.retainAll(al2);//取交集。al1中只会保留和al2中相同的元素。
		al1.removeAll(al2);

		sop("al1:"+al1);
		sop("al2:"+al2);
	}

	public static void base_method()
	{
		//创建一个集合容器,使用collection接口的子类。ArrayList
		ArrayList al = new ArrayList();

		//1.添加元素。
		al.add("java01");  //add(Object obj);
		al.add("java02");
		al.add("java03");
		al.add("java04");

		//打印原集合
		sop("原集合:"+al); //结果:[java01, java02, java03, java04]

		//3.删除元素。
		//al.remove("java02"); //结果:[java01, java03, java04]
		//al.clear();  //清空集合。结果为:[]

		//4.判断元素。
		sop("java03是否存在:"+al.contains("java03"));
		sop("集合是否为空?"+al.isEmpty());

		//2.获取个数,集合长度。
		sop("size:"+al.size());
		
		//打印改变后的集合。
		sop(al);
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}



四、List集合共性方法

1、ListIterator

List集合特有的迭代器:ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素。

因为会发生ConcurrentModificationException异常。所以,在迭代时,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。如果想要其他的操作,如添加、修改等。就需要使用其子接口,ListIterator。

该接口只能通过List集合的ListIterator方法获取。



2、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();

int indexOf(obj):获取指定元素的位置。

ListIterator 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,"java07");

		//通过角标获取元素。
		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.set("java06");
				//li.add("java009");
		}

		while (li.hasPrevious())
		{
			sop("previous::"+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"))
				it.remove();  //将java02的引用从集合中删除了。
				//al.add("java008");

			sop("obj="+obj);
		}
		sop("改变后的集合:"+al);
		*/


	}
}

3、Vector中的枚举

枚举就是Vector特有的取出方式。发现枚举和迭代器很像,其实枚举和迭代是一样的。

因为枚举的名称以及方法的名称都过长,所以被迭代器取代了。枚举郁郁而终了。

例如:

import java.util.*;

class VectorDemo 
{
	public static void main(String[] args) 
	{
		Vector v=new Vector();

		v.add("java01");
		v.add("java02");
		v.add("java03");
		v.add("java04");

		Enumeration en=v.elements();
		while (en.hasMoreElements())
		{
			System.out.println(en.nextElement());
		}
	}
}


4、LinkedList

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())
		{
			System.out.println(link.removeFirst());
		}
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}


5、ArrayList

/*
例如:去除ArrayList集合中的重复元素。
*/

import java.util.*;

class ArrayListTest 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}

	public static void main(String[] args) 
	{
		ArrayList al=new ArrayList();
		al.add("java01");
		al.add("java02");
		al.add("java01");
		al.add("java02");
		al.add("java01");
		al.add("java03");

		/*
		在迭代时循环中next调用一次,就要hasNext判断一次。
		
		Iterator it=al.iterator();
		while (it.hasNext())
		{
			sop(it.next()+"......"+it.next());
		}
		*/
		
		sop(al);
		al=singleElement(al);
		sop(al);
	}

	public static ArrayList singleElement(ArrayList al)
	{
		//定义一个临时容器。
		ArrayList newAl=new ArrayList();

		Iterator it=al.iterator();
		while (it.hasNext())
		{
			Object obj=it.next();
			if(!newAl.contains(obj))
				newAl.add(obj);
		}
		return newAl;
	}
}



五、Set

Set集合的功能和Collection是一致的。

|--Set:元素是无序(存入和取出的顺序不一定一致);元素不可以重复。

|--HashSet:底层数据结构是哈希表。线程是非同步的。

HashSet是如何保证元素唯一性的呢?

是通过元素的两个方法,hashCode和equals来完成。

如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashcode值不同,不会调用equals。

注意:对于判断元素是否存在,以及删除等操作,依赖的方法时元素的hashCode和equals方法。

|--TreeSet:可以对Set集合中的元素进行排序。

底层数据结构是二叉树。

保证元素唯一性的依据:compareTo方法return 0;

 

TreeSet排序的第一种方式:让元素自身具备比较性。

元素需要实现Comparable接口,覆盖compareTo方法。这种方式也称为元素的自然顺序,或者叫做默认顺序。

 

TreeSet的第二种排序方式:

当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式。

 

记住:排序时,当主要条件相同时,一定要判断一下次要条件。


1、HashSet

例如:

import java.util.*;

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));
		
		//sop("a1:"+hs.contains(new Person("a2",12)));
		hs.remove(new Person("a3",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 void setName(String name)
	{
		this.name=name;
	}
	
	public int getAge()
	{
		return age;
	}
	public void setAge(int age)
	{
		this.age=age;
	}
}


2、TreeSet

                TreeSet ts=new TreeSet();

		ts.add("cba");
		ts.add("abcd");
		ts.add("aaa");
		ts.add("bca");
		
		Iterator it=ts.iterator();
		while (it.hasNext())
		{
			System.out.println(it.next());
		}


3、实现Comparator方式排序

当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。

那么定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

当两种排序都存在时,以比较器为主。

怎样定义一个比较器呢?

定义一个类,实现Comparator接口,覆盖compare方法。

例如:

import java.util.*;
class Student implements Comparable //该接口强制让学生具备比较性。
{
	private String name;
	private int age;

	Student(String name,int age)
	{
		this.name=name;
		this.age=age;
	}
	//覆盖compareTo方法,按年龄排序
	public int compareTo(Object obj)
	{
		if(!(obj instanceof Student))
			throw new RuntimeException("不是学生对象!");
		Student s=(Student)obj;
		
		//System.out.println(this.name+"...compareto..."+s.name);
		if(this.age>s.age)
			return 1;
		if(this.age==s.age)
		{
			return this.name.compareTo(s.name);
		}
		return -1;
	}

	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}

class TreeSetDemo2 
{
	public static void main(String[] args) 
	{
                //TreeSet ts=new TreeSet();
		TreeSet ts=new TreeSet(new MyCompare());

		ts.add(new Student("lisi02",22));
		ts.add(new Student("lisi02",21));
		ts.add(new Student("lisi007",20));
		ts.add(new Student("lisi09",19));
		ts.add(new Student("lisi06",18));
		ts.add(new Student("lisi007",29));
		
		Iterator it=ts.iterator();
		while (it.hasNext())
		{
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"......"+stu.getAge());
		}
	}
}

//实现Comparator接口,覆盖compare方法。按姓名排序。
class MyCompare implements Comparator
{
	public int compare(Object o1,Object o2)
	{
		Student s1=(Student)o1;
		Student s2=(Student)o2;

		//return s1.getName().compareTo(s2.getName());

		int num=s1.getName().compareTo(s2.getName());
		if (num==0)
		{
			return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}
		return num;
	}
}



六、泛型

泛型:JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。

 

好处:

1,将运行时期出现的问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时期问题减少,安全。

2,避免了强制转换的麻烦。

 

泛型格式:通过<>来定义要操作的引用数据类型。

在使用java提供的对象时,什么时候写泛型呢?

  通常在集合框架中很常见,只要见到<>就要定义泛型。其实<>就是用来接收类型的。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

例如:

import java.util.*;

class GenericDemo 
{
	public static void main(String[] args) 
	{
		ArrayList<String> al=new ArrayList<String>(); //泛型

		al.add("abc01");
		al.add("abc0991");
		al.add("abc014");

		Iterator<String> it=al.iterator();
		while (it.hasNext())
		{
			String s=it.next();
			System.out.println(s+":"+s.length());
		}
	}
}


1、泛型类

什么时候定义泛型类?

当类中要操作的引用数据类型不确定的时候。早期定义Object来完成扩展。现在定义泛型来完成扩展。

例如:

class Worker
{
}
class Student
{
}

//泛型前做法
class Tool
{
	private Object obj;
	public void setObject(Object obj)
	{
		this.obj=obj;
	}
	public Object getObject()
	{
		return obj;
	}
}

//泛型类
class Utils<QQ>
{
	private QQ q;
	public void setObject(QQ q)
	{
		this.q=q;
	}
	public QQ getObject()
	{
		return q;
	}
}

class GenericDemo3 
{
	public static void main(String[] args) 
	{
		Utils<Worker> u=new Utils<Worker>();
		u.setObject(new Worker());
		//Worker w=(Worker)u.getObject();
		Worker w=u.getObject(); //不用强转
	}
}


2、泛型方法

泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。

  为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。


3、静态方法泛型

特殊之处:

静态方法不可以访问类上定义的泛型。如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。


泛型定义在方法上,放在哪?

<>放在返回值类型前面,修饰符的后面。

例如:

class Demo<T>	//泛型类
{
	public void show(T t)
	{
		System.out.println("show:"+t);
	}
	public <Q> void print(Q q)	//泛型方法
	{
		System.out.println("print:"+q);
	}
	public static <W> void method(W w)	//静态方法泛型
	{
		System.out.println("method:"+w);
	}
}

class GenericDemo4 
{
	public static void main(String[] args) 
	{
		Demo<String> d=new Demo<String>();
		d.show("haha");
		//d.show(4); //错误;泛型的类型已经固定。
		d.print(5);
		d.print("hehe");

		Demo.method("hahahaha"); //静态方法,类名调用
	}
}


4、泛型接口

//泛型定义在接口上。
interface Inter<T>
{
	void show(T t);
}

/*
//第一种方式:
class InterImpl implements Inter<String>
{
	public void show(String t)
	{
		System.out.println("show:"+t);
	}
}
*/

//第二种方式:
class InterImpl<T> implements Inter<T>
{
	public void show(T t)
	{
		System.out.println("show:"+t);
	}
}

class GenericDemo5 
{
	public static void main(String[] args) 
	{
		/*
		InterImpl i=new InterImpl();
		i.show("haha");
		*/
		
		InterImpl<Integer> i=new InterImpl<Integer>();
		i.show(4);
	}
}



七、泛型限定

? 通配符。也可以理解为占位符。

泛型的限定:

? extends E:可以接收E类型或者E的子类型。上限。

? super E:可以接收E类型或者E的父类型。下限。

例如:


import java.util.*;

class GenericDemo6 
{
	public static void main(String[] args) 
	{
		ArrayList<Person> al=new ArrayList<Person>();
		al.add(new Person("abc1"));
		al.add(new Person("abc2"));
		al.add(new Person("abc3"));

		ArrayList<Student> al1=new ArrayList<Student>();
		al1.add(new Student("abc--1"));
		al1.add(new Student("abc--2"));
		al1.add(new Student("abc--3"));

		printColl(al1); //ArrayList<Person> al=new ArrayList<Student>(); Error
	}

	public static void printColl(ArrayList<? extends Person> al) //泛型限定
	{
		Iterator<? extends Person> it=al.iterator();
		while (it.hasNext())
		{
			System.out.println(it.next().getName());
		}
	}
}

class Person
{
	private String name;
	Person(String name)
	{
		this.name=name;
	}
	public String getName()
	{
		return name;
	}
}

class Student extends Person
{
	Student(String name)
	{
		super(name);
	}
}




------- android培训java培训、期待与您交流! ----------


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chenweizuo/article/details/46833281

智能推荐

金融分析与风险管理——期权的隐含波动率_隐含波动率的迭代计算-程序员宅基地

文章浏览阅读2.3k次,点赞7次,收藏32次。金融分析与风险管理——期权的隐含波动率1. 隐含波动率的计算方法1.1 牛顿迭代法1.2 二分查找法2. 波动率微笑与斜偏2.1 波动率微笑2.2 波动率斜偏1. 隐含波动率的计算方法在期权市场上,可以直接观察到标的物当前价格(S)、期权的执行价格(K)、合约期限(T)以及无风险收益率(r),但是波动率不能直接观察。当然,我们可以通过标的物历史价格来估计波动率,但是在实际的应用中,通常会使用隐含波动率,隐含波动率可通过期权的市场价格、运用 BSM 模型进行计算。由于期权的定价公式非常复杂,不能直接通过反_隐含波动率的迭代计算

html 页面北京怎么设置,怎么给html设置背景色-程序员宅基地

文章浏览阅读900次。给html设置背景色的方法:首先创建一个HTML示例文件;然后通过给body或p标签等添加“background-color”属性来设置不同元素的背景色即可。本教程操作环境:Windows7系统、DELL G3电脑、HTML5&&CSS3。background-color属性设置一个元素的背景颜色。元素的背景是元素的总大小,包括填充和边界(但不包括边距)。实例设置不同元素的背景色:..._html 根据条件设置北京

html水平位置怎么设置,CSS如何使元素水平垂直定位-程序员宅基地

文章浏览阅读597次。作为一名前端工程师,在进行web页面开发的时候,可能会遇到这样一种问题:如何使一个元素相对父容器水平垂直居中,也就是所谓的绝对居中呢?这篇文章将会针对这个问题介绍几种常用的方法。谈到这个问题,相信有点经验的同学们可能心里已经有了答案了。不过,这篇文章将会从下面两种不同的应用场景分别阐述如何使用CSS让一个元素绝对居中,元素有明确的高度不知道元素的高度元素有明确的高度这种场景中,我们已经知道需要绝对..._前端如何设置某个元素水平绝对定位,垂直固定定位

小波分析c语言编程,小波分析算法的公式与C语言实现 - 全文-程序员宅基地

文章浏览阅读1k次。一、小波分析算法的计算1、Mallat算法[经典算法]在小波理论中,多分辨率分析是一个重要的组成部分。多分辨率分析是一种对信号的空间分解方法,分解的最终目的是力求构造一个在频率上高度逼近L2(R)空间的正交小波基,这些频率分辨率不同的正交小波基相当于带宽各异的带通滤波器。因此,对于一个能量有限信号,可以通过多分辨率分析的方法把其中的逼近信号和细节信号分离开,然后再根据需要逐一研究。多分辨率分析的概..._小波分析 c语言

Matlab将csv文件转换成mat文件,并读取的直观代码_csv转mat-程序员宅基地

文章浏览阅读4.3k次,点赞2次,收藏31次。这一步将path目录下的所有csv文件转换为mat文件,并且保存在mat数据文件目录下。第一步:csv文件转换为mat文件。第二步:读取mat文件。_csv转mat

mysql time_zone详解_MySQL中时区参数time_zone的修改-程序员宅基地

文章浏览阅读579次。首先需要查看mysql的当前时区,用time_zone参数mysql> show variables like '%time_zone%';+------------------+--------+| Variable_name | Value |+------------------+--------+| system_time_zone | CST || time_zone..._mysql time zone

随便推点

iOS面试 - runtime & 消息转发机制_oc消息转发机制面试-程序员宅基地

文章浏览阅读1.4k次。runtime1. 什么是runtime?runtime 运行时机制,是一套比较底层的纯 C 语言 API , 属于1个 C 语言库, 包含了很多底层的 C 语言 API 。(引入 <objc/runtime.h> 或者 <objc/message.h> )程序运行过程时,我们平时编写的 OC 代码, 其实最终都是转成了 runtime 的 C 语言代码。在编译..._oc消息转发机制面试

.NET桌面程序(WINFORM或WPF)的部署_windows server 系统可以运行winform程序么-程序员宅基地

文章浏览阅读1.4k次。目前的WIN7操作系统自带了.NET3.5,用户基数比较大,后面的WIN8,WIN10的自带.NET版本都不一样。WINDOWS SERVER操作系统默认的.NET是不启用的,需要手动启用.NET组件。由于桌面程序很少有在服务器系统上运行的,所以不考虑SERVER系统。在开发前端桌面程序时,以前的前端程序很多会用MFC开发,或者基于MFC的界面库进行开发,好处是不需要关心操作系统,可以直接运行。..._windows server 系统可以运行winform程序么

python图像处理_色彩转换_怎么把红色数码管图片转化成lcd图片python-程序员宅基地

文章浏览阅读3.5k次。1.RGB图像染色from skimage import data import matplotlib.pyplot as plt from skimage.color import rgb_from_bpx,bpx_from_rgb,separate_stains,combine_stains ihc=data.immunohistochemistry() ih..._怎么把红色数码管图片转化成lcd图片python

BW之数据源 增量管理DELTA(详细)_sap bw 后勤数据源的delta字段-程序员宅基地

文章浏览阅读473次。SAP中的增量机制,可以有助系统提高数据抽取效率,在初始化执行后,每天只更新新增和修改了的记录。在我们正常的使用或开发中,这些东西并不需要知道,只要数据正常上载,就好了,此处所介绍的内容之为大家参考用。在介绍DELTA机制之前,先介绍下DSO和CUBE:DSO:一般DSO用来存储明细数据,其结构比较简单。对于值的转换(决定了可用的DELTA类型),既可以使用合计,也可..._sap bw 后勤数据源的delta字段

SpringBoot 关于DataSource的一些配置属性记录_postgregsql spring.datasource.platform 属性填什么-程序员宅基地

文章浏览阅读3.3k次。原文: https://segmentfault.com/a/1190000004316491SpringBoot配置属性系列SpringBoot配置属性之MVCSpringBoot配置属性之ServerSpringBoot配置属性之DataSourceSpringBoot配置属性之NOSQLSpringBoot配置属性之MQSpringBoot配置属性之SecuritySpri..._postgregsql spring.datasource.platform 属性填什么

flume学习笔记(一):cdh5.14.2中安装,启动,测试flume_cdh flume使用-程序员宅基地

文章浏览阅读5.8k次。说明:此文特为初次使用cdh上flume,并且对flume有一定认识的同学参考使用,具体请参考官网: Apache Flume 环境:centos7.3 1708 ,cdh 5.14.21. 在cdh中添加flume服务看图: 图一 图二 图三 图四 图片五 图片六 在这里启动一下flume 图片七 图片八 2.使用默认配..._cdh flume使用