/**
* 最终版本:考虑存在顺序
* @author Administrator
*
*/
public class BubbleSort {
/**
* @param args
*/
public static void main(String[] args) {
int[] arr ={1,2,9,3,4};
sort1(arr);
System.out.println("==========final============");
arr =new int[]{9,1,2,3,4};
sortFinal(arr);
}
//第二版本,减少每一趟的次数
public static void sortFinal(int[] arr){
boolean sorted= true;
int len =arr.length;
for(int j=0;j<len-1;j++){ //趟数
sorted =true; //假定有序
for(int i=0;i<len-1-j;i++){ //次数
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] =arr[i+1];
arr[i+1] =temp;
sorted =false; //假定失败
}
System.out.println(Arrays.toString(arr));
}
if(sorted){ //减少趟数
break;
}
}
}
//第二版本,减少每一趟的次数
public static void sort1(int[] arr){
int len =arr.length;
for(int j=0;j<len-1;j++){ //趟数
System.out.println("第"+(j+1)+"趟");
for(int i=0;i<len-1-j;i++){ //次数
System.out.print("第"+(i+1)+"次");
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] =arr[i+1];
arr[i+1] =temp;
}
System.out.println(Arrays.toString(arr));
}
}
}
}
引用数据类型的排序:
排序的实体类都实现了:java.lang.Comparable接口,该接口中只有一个方法,public int compareTo(Object obj){}
返回0表示相等,正数表示大于,负数表示小于.
/**
* 内置引用数据类型(常用)的比较
* @author Administrator
*
*/
public class Demo01 {
/**
* @param args
*/
public static void main(String[] args) {
Integer a ; //根据基本数据类型大小
Character ch; //根据Unicode编码顺序
String str="abc"; //如果其中一个是例外一个起始开始的子串,返回长度之差
String str2 ="abcd123"; //否则返回第一个不相等的unicode码之差
System.out.println(str.compareTo(str2));
str ="abc";
str2 ="aad";
System.out.println(str.compareTo(str2));
java.util.Date d ; //根据日期的长整形数比较
}
}
package com.bjsxt.sort.innerType;
import java.util.Comparator;
import java.util.List;
/**
* 排序
* @author Administrator
*
*/
public class Utils {
/**
* List的排序+比较器
* @param list
* @param com
*/
public static <T> void sort(List<T> list,Comparator<T> com){
//第一步:转成数组
Object[] arr =list.toArray();
sort(arr,com);
//第二步:改变容器中对应的值
for(int i=0;i<arr.length;i++){
list.set(i, (T)(arr[i]));
}
}
/**
* 数组的排序 (降序)+Comparator接口
* @param arr
*/
public static <T> void sort(Object[] arr,Comparator<T> com){
//从大到小排序 降序
boolean sorted= true;
int len =arr.length;
for(int j=0;j<len-1;j++){ //趟数
sorted =true; //假定有序
for(int i=0;i<len-1-j;i++){ //次数
if(com.compare((T)arr[i], (T)arr[i+1])<0){
Object temp = arr[i];
arr[i] =arr[i+1];
arr[i+1] =temp;
sorted =false; //假定失败
}
}
if(sorted){ //减少趟数
break;
}
}
}
/**
* 容器排序 (使用泛型方法)
*/
public static <T extends Comparable<T>> void sort(List<T> list){
//第一步:转成数组
Object[] arr =list.toArray();
sort(arr);
//第二步:改变容器中对应的值
for(int i=0;i<arr.length;i++){
list.set(i, (T)(arr[i]));
}
}
/**
* 数组排序 (使用泛型方法)
*/
public static <T extends Comparable<T>> void sort(T[] arr){
//从大到小排序 降序
boolean sorted= true;
int len =arr.length;
for(int j=0;j<len-1;j++){ //趟数
sorted =true; //假定有序
for(int i=0;i<len-1-j;i++){ //次数
if(((Comparable)arr[i]).compareTo(arr[i+1])<0){
T temp = arr[i];
arr[i] =arr[i+1];
arr[i+1] =temp;
sorted =false; //假定失败
}
}
if(sorted){ //减少趟数
break;
}
}
}
/**
* 数组的排序 (降序)
* @param arr
*/
public static void sort(Object[] arr){
//从大到小排序 降序
boolean sorted= true;
int len =arr.length;
for(int j=0;j<len-1;j++){ //趟数
sorted =true; //假定有序
for(int i=0;i<len-1-j;i++){ //次数
if(((Comparable)arr[i]).compareTo(arr[i+1])<0){
Object temp = arr[i];
arr[i] =arr[i+1];
arr[i+1] =temp;
sorted =false; //假定失败
}
}
if(sorted){ //减少趟数
break;
}
}
}
}
/**
* 排序规则的业务类
* @author Administrator
*
*/
public class StringComp implements java.util.Comparator<String>{
/**
* 按长度比较大小
* 正数 >
* 负数 <
* 0 ==
*/
@Override
public int compare(String o1, String o2) {
int len1 =o1.length();
int len2 =o2.length();
return -(len1-len2);
}
}
comparator 接口:提供排序的比较器,业务比较器.需要重写compare方法.
其独立于实体类,方便应用各种业务规则.
package com.bjsxt.sort.innerType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 使用Collections对容器的比较
* 1、 public static <T> void sort(List<T> list, Comparator<? super T> c)
* 2、public static <T extends Comparable<? super T>> void sort(List<T> list)
* void sort(List<T> list)
* @author Administrator
*
*/
public class Demo05 {
/**
* @param args
*/
public static void main(String[] args) {
List<String> list =new ArrayList<String>();
list.add("a");
list.add("abcd");
list.add("abc");
list.add("def");
Collections.sort(list,new StringComp());
System.out.println(list);
list =new ArrayList<String>();
list.add("a");
list.add("abcd");
list.add("abc");
list.add("def");
Collections.sort(list);
System.out.println(list);
}
}
自定义数据排序:
package basic;
import java.text.SimpleDateFormat;
import java.util.Date;
public class NewsItem implements Comparable<NewsItem> {
private String title; //标题
private int hits; //点击量
private Date pubTime; //发布时间
public NewsItem(){}
public NewsItem(String title,int hits,Date pubTime){
super();
this.hits=hits;
this.title=title;
this.pubTime=pubTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getHits() {
return hits;
}
public void setHits(int hits) {
this.hits = hits;
}
public Date getPubTime() {
return pubTime;
}
public void setPubTime(Date pubTime) {
this.pubTime = pubTime;
}
//时间降序,点击量升序,标题降序
@Override
public int compareTo(NewsItem o) {
// TODO Auto-generated method stub
int result=0;
//时间降序
result=-this.pubTime.compareTo(o.pubTime);
if(0==result)
result=this.hits-o.hits; //升序
if(0==result)
result=-this.title.compareTo(o.title);
return result;
}
public String toString(){
StringBuilder sb=new StringBuilder();
sb.append("标题:").append(this.title);
sb.append("时间:").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime));
sb.append("点击量:").append(this.hits).append("\n");
return sb.toString();
}
/**
* 使用Collections
* @author Administrator
*
*/
public class NewsItemApp {
/**
* @param args
*/
public static void main(String[] args) {
List<NewsItem> news=new ArrayList<NewsItem>();
news.add(new NewsItem("美国后怕了,逃跑了悲剧了",50,new Date(System.currentTimeMillis()-1000*60*60)));
news.add(new NewsItem("中国登上钓鱼岛了,全国欢呼了",100,new Date()));
news.add(new NewsItem("小日本终于听话了,泪流满面笑了",60,new Date(System.currentTimeMillis()-1000*60*60)));
System.out.println("排序前:"+news);
//排序
//Collections.sort(news); //会调用NewsItem本身的compareTo方法
Utils.sort(news);
System.out.println("排序后"+news);
}
提供排序的比较器,业务比较器:
/**
* 按价格排序的业务类 (降序)
* @author Administrator
*
*/
public class GoodsPriceComp implements java.util.Comparator<Goods> {
@Override
public int compare(Goods o1, Goods o2) {
return -(o1.getPrice()-o2.getPrice()>0?1:(o1.getPrice()==o2.getPrice()?0:-1));
}
}
/**
* 按收藏量排序的业务类 (升序)
* @author Administrator
*
*/
public class GoodsFavComp implements java.util.Comparator<Goods> {
@Override
public int compare(Goods o1, Goods o2) {
return o1.getFav()-o2.getFav();
}
}
/**
* @param args
*/
public static void main(String[] args) {
List<Goods> list =new ArrayList<Goods>();
list.add(new Goods("老马视频",100,2000));
list.add(new Goods("老高视频",50,2000));
list.add(new Goods("老裴视频",1000,1000));
System.out.println("排序前:"+list);
// Collections.sort(list,new GoodsPriceComp());
Collections.sort(list,new GoodsFavComp());
System.out.println("排序后:"+list);
}
}
TreeMap:确保key可以排序或者提供排序器.
public TreeMap(Comparator<? super k> comparator){}
TreeSet:确保元素实体可以排序或者提供排序器
public TreeSet(Comparator<? super k> comparator){}
TreeSet:数据元素可以排序且不可重复,在HashSet中,元素必须重写hashcode,equals方法.TreeSet不需要
去重:比较等于0即重复.
1.元素可以排序,实现java.lang.comparable接口.重写compareTo方法. 选择空构造器即可,new TreeSet()
2.排序业务类:java.util.Comparator+compare方法. 选择 :TreeSet(Comparator<? super k> comparator){}
/**
* 提供了 解耦的方式:业务排序类
* @author Administrator
*
*/
public class TreeSetDemo {
/**
* @param args
*/
public static void main(String[] args) {
Person p1 =new Person("您",100);
Person p2 =new Person("刘德华",1000);
Person p3 =new Person("梁朝伟",1200);
Person p4 =new Person("老裴",50);
//依次存放到TreeSet容器中,使用排序的业务类(匿名内部类)
TreeSet<Person> persons =new TreeSet<Person>(
new java.util.Comparator<Person>(){
@Override
public int compare(Person o1, Person o2) {
return -(o1.getHandsome()-o2.getHandsome());
}
}
);
persons.add(p1);
//TreeSet 在添加数据时排序
persons.add(p2);
persons.add(p3);
persons.add(p4);
System.out.println(persons);
/*
//改变数据
p4.setHandsome(100);
p4.setName("您");
*/
//p4 与p1 内容重复
System.out.println(persons);
}
}
public class Worker implements java.lang.Comparable<Worker> {
//工种
private String type;
//工资
private double salary;
public Worker() {
// TODO Auto-generated constructor stub
}
public Worker(String type, double salary) {
super();
this.type = type;
this.salary = salary;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
/**
* 按工资升序
*/
@Override
public int compareTo(Worker o) {
return this.salary>o.salary?1:( this.salary==o.salary?0:-1);
}
@Override
public String toString() {
return "工种:"+this.type+",工资:"+this.salary+"\n";
}
}
import java.util.TreeSet;
/**
* 实体类实现Comparable 接口的应用
* @author Administrator
*
*/
public class TreeSetDemo2 {
/**
* @param args
*/
public static void main(String[] args) {
Worker w1 =new Worker("垃圾回收员",12000);
Worker w2 =new Worker("农民工",8000);
Worker w3 =new Worker("程序猿",5000);
TreeSet<Worker> employees =new TreeSet<Worker>();
employees.add(w1);
employees.add(w2);
employees.add(w3);
System.out.println(employees);
}
}
public class TreeMapDemo {
/**
* @param args
*/
public static void main(String[] args) {
Person p1 =new Person("您",100);
Person p2 =new Person("刘德华",1000);
Person p3 =new Person("梁朝伟",1200);
Person p4 =new Person("老裴",50);
TreeMap<Person,String> map =new TreeMap<Person,String>(new java.util.Comparator<Person>(){
@Override
public int compare(Person o1, Person o2) {
return -(o1.getHandsome()-o2.getHandsome());
}
} );
map.put(p1, "bjsxt");
map.put(p2, "bjsxt");
map.put(p3, "bjsxt");
map.put(p4, "bjsxt");
//查看键
Set<Person> persons =map.keySet();
System.out.println(persons);
}
}
ublic class TreeMapDemo02 {
/**
* @param args
*/
public static void main(String[] args) {
Worker w1 =new Worker("垃圾回收员",12000);
Worker w2 =new Worker("农民工",8000);
Worker w3 =new Worker("程序猿",5000);
TreeMap<Worker,String > employees =new TreeMap<Worker,String >();
employees.put(w1,"bjsxt");
employees.put(w2,"bjsxt");
employees.put(w3,"bjsxt");
System.out.println(employees.keySet());
}
}
TreeSet在添加数据时排序,数据更改不会影响原来的顺序,不要修改顺序,否则有可能重复.
Collections常用算法:
在写完代码后,使用格式刷刷一下,ctrl+shift+F.此之前,设置myeclipse每行显示的最大长度改高.默认80,改成200.
然后显示出tab标记,显示出末尾和开头的空格标记,show white spaces中,主题改成黑色,Monokai.字体consolas,五号.
MyEclipse 格式化代码调整每行长度默认每行是80~对于咱初学者,非敏捷型编码者来说~有点短 以至于Ctrl+Shift+F 格式化代码后总把一行拆成两行或者更多有点不适应 所以按个人爱好 更改他 这里介绍的是MyEclipse8.5的更改方式其他应该差不多 Window→Preferences→Java→Code Style→ Formatter 右侧 可以直接Edit也可以New,建议自己New。 Line Wrapping选项卡的 左上Maximum line width的值是80,改成自己适合的值。Collections的常用方法:
/**
*1、 binarySearch(List<? extends Comparable<? super T>> list, T key) 容器有序
*2、sort(List<T> list)
sort(List<T> list, Comparator<? super T> c)
*3、reverse(List<?> list)
4、shuffle(List<?> list) 洗牌
5、swap(List<?> list, int i, int j)
* @author Administrator
*
*/
public class CollectionsDemo01 {
/**
* @param args
*/
public static void main(String[] args) {
List<Integer> cards =new ArrayList<Integer>();
//shuffle 洗牌 模拟斗地主
for(int i=0;i<54;i++){
cards.add(i);
}
//洗牌
Collections.shuffle(cards) ;
//依次发牌
List<Integer> p1 =new ArrayList<Integer>();
List<Integer> p2 =new ArrayList<Integer>();
List<Integer> p3 =new ArrayList<Integer>();
List<Integer> last =new ArrayList<Integer>();
for(int i=0;i<51;i+=3){
p1.add(cards.get(i));
p2.add(cards.get(i+1));
p3.add(cards.get(i+2));
}
//最后三张为底牌
last.add(cards.get(51));
last.add(cards.get(52));
last.add(cards.get(53));
System.out.println("第一个人:"+p1);
System.out.println("第二个人:"+p2);
System.out.println("第三个人:"+p3);
System.out.println("底牌为:"+last);
}
//反转
public static void test1(){
List<Integer> list =new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
System.out.println(list);
Collections.reverse(list);
System.out.println("反转之后"+list);
}
}
队列:Queue与Deque 单向与双向
开源工具包:Guaua:::Google Collection .Aache Commons Collection
public class Basic {
public static void main(String[] args) throws ParseException {
Queue<Request> queue=new ArrayDeque<>();
for(int i=0; i<10;i++){
final int num=i; //匿名类对象只能访问final类型的变量
queue.offer(new Request() {
@Override
public void deposit() {
// TODO Auto-generated method stub
System.out.println("第"+num+"个人办理存款业务");
}
});
}
dealwith(queue);//先进先出
}
public static void dealwith(Queue<Request> queue){
Request request=null;
while(null!=(request=queue.poll())){
request.deposit();
}
}
interface Request{
//存款
void deposit();
}
}
使用双端队列模拟栈::::::
public class MyStack<E> {
//容器
private Deque<E> container=new ArrayDeque<>();//使用双端队列模拟栈
//容量
private int cap;
public MyStack(int cap) {
super();
this.cap = cap;
}
//压栈
public boolean push(E e){
if(container.size()+1>cap){
return false;
}
return container.offerLast(e);//插入到最后
}
//出栈
public E pop(){
return container.pollLast();
}
//获取
public E peek(){
return container.peekLast();
}
public int size(){
return this.container.size();
}
}
比较古老的接口,枚举Enumeration.作用和Iterator类似,在以前的JDK版本中用的非常的多.都是输出数据的方法.
Vector<String> vector=new Vector<>();
vector.add("ee");
vector.add("eeww");
vector.add("eew");
Enumeration<String> enumeration=vector.elements();
while(enumeration.hasMoreElements()){
System.out.println(enumeration.nextElement());
}
String tesString="aaa,bbb,ccc,ddd,eee,fff";
StringTokenizer st=new StringTokenizer(tesString,",");//StringTokenizer实现了Enumeration接口
while (st.hasMoreElements()) {
System.out.println(st.nextElement());
}
hashTable及其子类:Properties
HashTable:Map实现类,与HashMap操作相同.
HashMap线程不安全,HashTable线程安全.
HashMap键最多一个null,值可以为多个null. HashTable键和值都不能为null.
HashMap的父类:AbstractMap,,,HashTable的父类:Dictionary
Properties::::键与值只能为字符串.
常用方法::::
getProperty(String key)
setProperty(String key,String value)
store(OutputStream os,String comments)
storeToXML
load(InputStream in)
loadFromXML(InputStream in)
public class Basic {
public static void main(String[] args) throws ParseException, FileNotFoundException, IOException {
//Properties资源配置文件的读写
Properties pro=new Properties();
pro.setProperty("name", "che");
pro.setProperty("name2", "chejinqiang");
pro.setProperty("name3", "chejinqiang");
pro.setProperty("name4", "chejinqiang");
String aString=pro.getProperty("name","defalutValue");
//输出到文件
pro.store(new FileOutputStream(new File("d:/others/d.properties")),"db配置");
pro.storeToXML(new FileOutputStream(new File("d:/others/d.xml")),"db配置");
//使用相对路径,默认路径是当前的工程
pro.store(new FileOutputStream(new File("src/d.properties")),"db配置");
//读取配置文件,字符流
pro.load(new FileReader("d:/others/d.properties"));
pro.load(new FileReader("d.properties"));
//使用类相对路径读取配置 /代表类根目录 bin
pro.load(Basic.class.getResourceAsStream("/d.properties"));
//""代表类根目录 bin
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("d.properties"));
}
}
引用分类: 避免对象长期驻留在内存中
强引用:StrongReference,引用指向对象,gc运行时不回收.
软引用:gc运行时可能回收,jvm内存不够.
弱引用:运行时立即回收.
虚引用:类似于无引用,主要跟踪对象被回收的状态,不能单独使用.必须与引用队列联合使用.
WeakHashMap:键为弱引用,回收键后自动删除键值对象.
public static void main(String[] args) throws ParseException, FileNotFoundException, IOException {
//字符串常量池,共享,不能回收
String string="che jin qiang is a gold";
//弱引用管理对象
WeakReference<String> s=new WeakReference<String>(string);
System.out.println("gc运行前:"+s.get());
//断开引用
string=null;
//通知gc回收
System.gc();
System.runFinalization();
System.out.println("gc运行后:"+s.get());//与上述一样,表示常量池的对象不能够回收.
//该对象不是共享的,在堆 中
String string2=new String("che jin qiang is a gold");
//弱引用管理对象
WeakReference<String> s2=new WeakReference<String>(string2);
System.out.println("gc运行前:"+s2.get());
//断开引用
string2=null;
//通知gc回收
System.gc();
System.runFinalization();
System.out.println("gc运行后:"+s2.get());//null, 表示已经回收
}
//如果hashmap内用大量内存,你想清理可以使用这个方法
WeakHashMap<String, String> w=new WeakHashMap<>();
w.put("aaa", "aaa");
w.put("bbb", "ccc");
w.put(new String("aaaa"), "bbbb");//gc运行回收
w.put(new String("bbbb"), "cccc");//gc运行回收
System.gc();
System.runFinalization();
System.out.print(w.size());//2,常量池的两个不能清空,堆 上的两个已经清空
IdentityHashMap<String, String> map=new IdentityHashMap<>();
map.put("a", "a");
map.put("a", "b");
System.out.print(map.size());//1,常量池中两个内存地址一样
map.put(new String("a"), "a");
map.put(new String("a"), "a");
System.out.print(map.size());//3,堆上的是两个不同的内存地址
public class Basic {
public static void main(String[] args) throws ParseException, FileNotFoundException, IOException {
EnumMap<season, String> enumMap=new EnumMap<>(season.class);
enumMap.put(season.spring, "aa");
enumMap.put(season.summer, "bb");
enumMap.put(season.automn, "ccc");
enumMap.put(season.winter, "ddd");
System.out.print(enumMap.size());//4
}
}
enum season{
spring,summer,automn,winter
}
同步控制:多线程并发访问集合的线程安全.
hashSet,hashMap,arrayList都是线程不安全的.
collections类提供了synchronizedXxx()方法,将指定容器包装成同步的.synchronizedMap(),synchronizedList,synchronizedSet
List<String> list=new ArrayList<>();
list.add("aaa");
list.add("bbb");
List<String> lsList=Collections.synchronizedList(list);//同步,线程安全了
只读设置:有些容器你只希望只读,不希望修改.Collections提供了三种方法
emptyXxx()空的不可变的集合 避免空指针异常 return Collections.EMPTY_SET;
singletonXxx()一个元素不可变的集合,只能放一个元素的容器
unmodifiableXxx()不可变容器
Guava:google工程师利用传说中的百分之二十的时间开发的集合库,提供了很多实用的类进行扩展.
谷歌公司与apache组织编写好的类.
使用git下载源码:
下载客户端:mysgit:
git clone 目标地址 你的存储位置 下载源码,把api文档也下载下来.
HugeChm.rar可以将html的api 文档转换成chm格式.
下载源代码后可以关联到项目当中来.buildpath配置.
apache Commons collection直接到官网下载即可.