java 控制台显示输出柱状图 ,生成字符组成柱状图

在开发过程中,想要更直观的查看数组的分布情况,特编写了一个在控制台生成柱状图的工具类:

主要支持数组类型:

1、Integer[]

2、Double[]

3、Long[]



模块一:工具类

package tool;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by yy on 2017/11/1.
 * 柱状图的控制台显示工具类
 * 1、获取Y轴的显示数据
 * 2、比较对应的数据获取显示的柱状
 * 3、计算出最佳的每一行显示的数值
 * 4、将数组合的数据拼接后输出到控制台
 */
public class HistogramConsole {

    private static final int LINE_NUMBER=20; //显示的列的行数
    private static final String ALL_PRINT="█";//满的柱状
    private static final String LINE_PRINT="─";//横线
    private static final String LINE_NUMBER_PRINT="┬";//横坐标
    private static final String ROW_NUMBER_PRINT="┤";//纵坐标
    private static final String WRAP="\n";//换行
    private static final String SPACE=" ";//空格
    /**
     * 接收一个数字类型数组,根据穿进来的数组内容,将数据以柱状图的形式显示到控制台
     * 获取当前数组的最大值,然后根据显示
     * @param array 数字类型数组
     * @throws Exception 抛出对应的处理异常
     */
    public static  void echo(Comparable[] array)throws Exception{
        StringBuilder print=new StringBuilder();
        StringBuilder printX=new StringBuilder();
        StringBuilder printN=new StringBuilder();
        Boolean check=true;
        Boolean checkA=true;
        //获取y轴的数据
        Comparable[] YAxis=getArrayYAxis(array);
        //获取最大的显示长度
        int lengthY=getArrayDataLength(YAxis)+2;
        int lengthX=getArrayDataLength(array)+2;
        //获取显示的数据
        for(int i=0;i<YAxis.length;i++){
            //获取y坐标
            String YInfo=YAxis[i].toString()+ROW_NUMBER_PRINT;
            print.append(getStringRight(YInfo,lengthY));
            for(int k=0;k<array.length;k++){
                //获取柱状
                if (Double.valueOf(YAxis[i].toString())
                        .compareTo(Double.valueOf(array[k].toString()))<=0) {
                    print.append(getStringMiddle(ALL_PRINT, lengthX));
                }else{
                    print.append(getStringMiddle(LINE_PRINT, lengthX));
                }
                //获取显示的数字
                if(checkA) {
                    printX.append(getStringMiddle(array[k].toString(), lengthX));
                }
            }
            print.append(WRAP);
            //获取显示的x轴
            if(check){
                for(int k=0;k<(print.length()-lengthY)/2+(array.length)/2;k++){
                    printN.append(LINE_NUMBER_PRINT);
                }
                printN.append(WRAP);
                //获得一次数据后不再循环
                check=false;
                checkA=false;
            }
        }
        //拼接x轴和数字
        print.append(getStringRight("",lengthY)).append(printN)
                .append(getStringRight("",lengthY)).append(printX);
        System.out.println(print);
    }

    /**
     * 获取数组中最长的值的长度
     * @param array 传入数组长度
     * @return 返回最大长度
     */
    private static int getArrayDataLength(Object[] array){
        int length=0;
        for(int i=0;i<array.length;i++){
            length=length<array[i].toString().length()?array[i].toString().length():length;
        }
        return length;
    }
    /**
     * 获取Y轴循环使用的数组
     * 1、将传进来的数据转成Double,比较
     * 2、将获取最大值和最小区间,然后截取显示行数的数据(使用BigDecimal控制精度)
     * @param array 传入的数组
     * @return 返回Y轴循环使用的数组,降序
     */
    private static Comparable[] getArrayYAxis(Comparable[] array){
        //获取最大值和最小值
        Map<String,Comparable> MaxAndMin=getMaxAndMin(array);
        Double[] back=new Double[LINE_NUMBER];
        String max=MaxAndMin.get("max").toString();
        String min=MaxAndMin.get("min").toString();
        //判断最小值是否小于零,小于零区间会更大
        Boolean negative=Double.valueOf(min).compareTo(Double.valueOf(1))<0;
        Double all=negative?(Double.valueOf(max)-Double.valueOf(min)):Double.valueOf(max);
        //每行代表的数值.保留两位小数
        Double line=all/LINE_NUMBER;
        for (int i=0;i<LINE_NUMBER;i++){
            back[i]=Double.valueOf(max)-(line*i);
            BigDecimal   b   =   new BigDecimal(back[i]);
            back[i]=b.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        return back;
    }
    /**
     * 获取传去数组的最大值和最小值
     * @param array 传入数组
     * @return 最大值的key是max,最小值的key是min
     */
    private static Map<String,Comparable> getMaxAndMin(Comparable[] array){
        Map<String,Comparable> data=new HashMap<String, Comparable>();
        data.put("max",array[0]);
        data.put("min",array[0]);
        for(int i=0;i<array.length;i++){
            if(data.get("max").compareTo(array[i])<0){
                data.put("max",array[i]);
            }
            if(data.get("min").compareTo(array[i])>0){
                data.put("min",array[i]);
            }
        }
        return data;
    }
    /**
     * 获取传入长度的字符,根据传入的信息,左对齐
     * @param info 需要显示的内容
     * @param length 需要显示的长度,不够长度使用空格补充
     * @return 左对齐的字符信息
     */
    private static String getStringRight(String info,int length){
        StringBuilder data=new StringBuilder();
        for(int i=0;i<length-info.length();i++){
            data.append(SPACE);
        }
        data.append(info);
        return data.toString();
    }

    /**
     * 居中显示传入的字符信息,获取真实的长度,不够则补全,返回给定长度的字符串
     * @param info 传入的需要显示的字符
     * @param length 需要显示的长度
     * @return 返回居中显示的字符
     */
    private static String getStringMiddle(String info,int length){
        //获取字符串的真真实长度
        int trueLength=info.replaceAll("[^\\x00-\\xff]", "**").length();
        int lengthX=(length-trueLength)/2;
        StringBuilder data=new StringBuilder();
        StringBuilder dataX=new StringBuilder();
        for(int i=0;i<lengthX;i++){
            data.append(SPACE);
        }
        data.append(new StringBuffer(info).append(data));
        //补全不够的长度
        for (int k=0;k<length-data.toString().replaceAll("[^\\x00-\\xff]", "**").length();k++){
            dataX.append(SPACE);
        }
        return dataX.append(data).toString();
    }

}

模块二:测试

package tool;

/**
 * Created by yy on 2017/11/2.
 * 柱状图工具测试
 */
public class HistogramConsoleTest {
    public static void main(String[] args){
        try {
            Integer[] integers = new Integer[]{1, 2, -5, 15, 1, 6, 7, 8, 7, 10,15};
            Double[] dou = new Double[]{1.7, 2.9, 5.0, 6.6, 1.0, 6.9, 17.9, 8.2, 7.9, 10.0};
            Long[] lon = new Long[]{new Long("-1445354"), new Long("1346367"), new Long("9999999"),
                    new Long("-12352"), new Long("1"), new Long("1346367"), new Long("9999999")};
            HistogramConsole.echo(integers);
            HistogramConsole.echo(dou);
            HistogramConsole.echo(lon);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

模块三:结果


模块四:总结

因为这个方法并没有,用于实际的项目中,只是自己在开发的时候使用,之中还有很多问题,希望大家多多指教。

*注意:在不同的编码以及不同编辑器下显示效果会有所偏移,以上截图是在window记事本下打开的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值