java Spanny

Spanny.java
/**
 * Spannable wrapper for simple creation of Spannable strings.
 */
public class Spanny extends SpannableStringBuilder {

    private int flag = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE;

    public Spanny() {
        super("");
    }

    public Spanny(CharSequence text) {
        super(text);
    }

    public Spanny(CharSequence text, Object... spans) {
        super(text);
        for (Object span : spans) {
            setSpan(span, 0, length());
        }
    }

    public Spanny(CharSequence text, Object span) {
        super(text);
        setSpan(span, 0, text.length());
    }

    /**
     * Appends the character sequence {@code text} and spans {@code spans} over the appended part.
     * @param text the character sequence to append.
     * @param spans the object or objects to be spanned over the appended text.
     * @return this {@code Spanny}.
     */
    public Spanny append(CharSequence text, Object... spans) {
        append(text);
        for (Object span : spans) {
            setSpan(span, length() - text.length(), length());
        }
        return this;
    }

    public Spanny append(CharSequence text, Object span) {
        append(text);
        setSpan(span, length() - text.length(), length());
        return this;
    }

    /**
     * Add the ImageSpan to the start of the text.
     * @return this {@code Spanny}.
     */
    public Spanny append(CharSequence text, ImageSpan imageSpan) {
        text = "." + text;
        append(text);
        setSpan(imageSpan, length() - text.length(), length() - text.length() + 1);
        return this;
    }

    /**
     * Append plain text.
     * @return this {@code Spanny}.
     */
    @Override public Spanny append(CharSequence text) {
        super.append(text);
        return this;
    }

    /**
     * @deprecated use {@link #append(CharSequence text)}
     */
    @Deprecated public Spanny appendText(CharSequence text) {
        append(text);
        return this;
    }

    /**
     * Change the flag. Default is SPAN_EXCLUSIVE_EXCLUSIVE.
     * The flags determine how the span will behave when text is
     * inserted at the start or end of the span's range
     * @param flag see {@link Spanned}.
     */
    public void setFlag(int flag) {
        this.flag = flag;
    }

    /**
     * Mark the specified range of text with the specified object.
     * The flags determine how the span will behave when text is
     * inserted at the start or end of the span's range.
     */
    private void setSpan(Object span, int start, int end) {
        setSpan(span, start, end, flag);
    }

    /**
     * Sets a span object to all appearances of specified text in the spannable.
     * A new instance of a span object must be provided for each iteration
     * because it can't be reused.
     *
     * @param textToSpan Case-sensitive text to span in the current spannable.
     * @param getSpan    Interface to get a span for each spanned string.
     * @return {@code Spanny}.
     */
    public Spanny findAndSpan(CharSequence textToSpan, GetSpan getSpan) {
        int lastIndex = 0;
        while (lastIndex != -1) {
            lastIndex = toString().indexOf(textToSpan.toString(), lastIndex);
            if (lastIndex != -1) {
                setSpan(getSpan.getSpan(), lastIndex, lastIndex + textToSpan.length());
                lastIndex += textToSpan.length();
            }
        }
        return this;
    }

    /**
     * Interface to return a new span object when spanning multiple parts in the text.
     */
    public interface GetSpan {

        /**
         * @return A new span object should be returned.
         */
        Object getSpan();
    }

    /**
     * Sets span objects to the text. This is more efficient than creating a new instance of Spanny
     * or SpannableStringBuilder.
     * @return {@code SpannableString}.
     */
    public static SpannableString spanText(CharSequence text, Object... spans) {
        SpannableString spannableString = new SpannableString(text);
        for (Object span : spans) {
            spannableString.setSpan(span, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return spannableString;
    }

    public static SpannableString spanText(CharSequence text, Object span) {
        SpannableString spannableString = new SpannableString(text);
        spannableString.setSpan(span, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannableString;
    }
}

java 可赎回和可运行使用示例

可调用类使用示例

CallableImpl
package com.callable.runnable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Created on 2016/5/18.
 */
public class CallableImpl implements Callable<String> {

    public CallableImpl(String acceptStr) {
        this.acceptStr = acceptStr;
    }

    private String acceptStr;

    @Override
    public String call() throws Exception {
        // 任务阻塞 1 秒
        Thread.sleep(1000);
        return this.acceptStr + " append some chars and return it!";
    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<String> callable = new CallableImpl("my callable test!");
        FutureTask<String> task = new FutureTask<>(callable);
        long beginTime = System.currentTimeMillis();
        // 创建线程
        new Thread(task).start();
        // 调用get()阻塞主线程,反之,线程不会阻塞
        String result = task.get();
        long endTime = System.currentTimeMillis();
        System.out.println("hello : " + result);
        System.out.println("cast : " + (endTime - beginTime) / 1000 + " second!");
    }
}

java 合并间隔

合并区间段。先按照开始每个区间段的开始位置排序,然后判断分组段是否要和当前段合并。

simple
public List<Interval> merge(ArrayList<Integer> intervals){
    if(intervals==null || intervals.size()<=1)
        return intervals;
    
    Collections.sort(intervals,new IntervalComparator());

    ArrayList<Interval> result = new ArrayList<Interval>();
    Interval prev = intervals.get(0);
    for(int i = 1; i < intervals.size(); i++){
        Interval curr = intervals.get(i);
        if(prev.end >= curr.start){
            Interval merged = new Interval(prev.start,Math.max(prev.end,curr.end));
            prev = merged;
        }else{
            result.add(prev);
            prev = curr;
        }
    }
    result.add(prev);
    return result;
}
class IntervalComparator implements Comparator<Interval>{
    public int comparator(Interval v1,Interval v2){
        return v1.start-v2.start;
    }
}

java 两个排序数组的中位数 - 找两个有序数组的中位数

原题是求两个有序数组第ķ小的数。有两个数组甲和B,长度分别是米和ñ。首先假设数组甲和乙的元素个数都大于K / 2,我们比较A [ K / 2-1]和B [K / 2-1]两个元素,这两个元素分别表示甲的第K / 2小的元素和乙的第K / 2小的元素。这两个元素比较共有三种情况:>,<=和如果A [K / 2-1] <B [K / 2-1],这表示A [0]到A [K / 2-1]的元素都在甲和乙合并之后的前ķ小的元素中。换句话说,A [K / 2-1]不可能大于两数组合并之后的第ķ小值,所以我们可以将其抛弃。证明也很简单,可以采用反证法。假设A [K / 2-1]大于合并之后的第ķ小值,我们不妨假定其为第(K + 1)小值。由于A [K / 2-1]小于B [K / 2 -1],所以B [K / 2-1]至少是第(K + 2)小值。但实际上,在A中至多存在K / 2-1个元素小于A [K / 2-1], B中也至多存在k / 2-1个元素小于A [k / 2-1],所以小于A [k / 2-1]的元素个数至多有k / 2 + k / 2-2,小于k ,这与A [K / 2-1]是第(K + 1)的数矛盾。当A [K / 2-1]> B [K / 2-1]时在类似的结论。当A [K / 2-1] = B [K / 2-1]时,我们已经找到了第ķ小的数,也即这个相等的元素,我们将其记为米。由于在甲和乙中分别有K / 2-1个元素小于米,所以米即是第ķ小的数。(这里可能有人会有疑问,如果ķ为奇数,则米不是中位数。这里是进行了理想化考虑,在实际代码中略有不同,是先求K / 2,然后利用KK / 2获得另一个数。)通过上面的分析,我们即可以采用递归的方式实现寻找第ķ小的数。此外我们还需要考虑几个边界条件:如果阿或者乙为空,则直接返回B [K-1]或者A [K-1];如果ķ为1,我们只需要返回A [0]和B [ 0]中的较小值;如果A [K / 2-1] = B [K / 2-1],返回其中一个这是个递归过程,每次ķ都会变化,并且都会有K / 2的数被排除掉,K会变成K-(K / 2),时间复杂度是O(稳定常数)。

mid of two sorted arrays
double findKth(int[] a,int m,int [] b,int n,int k){
  if(m > n) return findKth(b,n,a,m,k);
  if (m==0) return b[k-1];
  if(k==1) return min(a[0],b[0]);
  int pa = min(k/2,m),pb=k-pa;
  int[] left_arr= new int[m-pa];
  System.arrayCopy(a,pa+1,left_arr,0,m-pa);
  if(a[pa-1] < b[pb-1]) return findKth(left_arr,m-pa,b,n,k-pa);//a的中位数小于b的,则需要剪掉a前半段
  int[] right_arr = new int[n-pb];
  System.arrayCopy(b,pb+1,right_arr,0,n-pb);
  if(a[pa-1] > b[pb-1]) return findKth(a,m,right_arr,n-pb,k-pb);//a的中位数大于b的则需要剪掉b的前半段
  return a[pa-1];//如果a的中位数和b的中位数相等则直接返回。
}
public double midValue(int [] a,int [] b,int m,int n){
  int t = m+n;
  if(t%2==1)
    return findKth(a,m,b,n,t/2+1);
  else 
    return (findKth(a,m,b,n,t/2)+findKth(a,m,b,n,t/2+1))/2;
}

java max gap找最大间距

给定一个数组无序,求排序之后两个相邻的数之间间隔最大是多少。时间和空间复杂度是O(N)。

bucket-sort
public int maximumGap(int [] nums){
  if(nums==null || nums.length==0) return 0;
  int mx = Integer.MIN_VALUE,mn=Integer.MAX_VALUE,n=nums.length;
  for(int i = 0 ; i < n; i++){
    mx = max(mx,nums[i]);
    mn = min(mn,nums[i]);
  }
  
  int size = (mx-mn)/n+1;
  int bucket_num = (mx-mn)/size+1;
  int[] bucket_min = new int[bucket_num]{Integer.MAX_VALUE};
  int[] bucket_max = new int[bucket_num]{Integer.MIN_VALUE};
  Set<Integer> s = new TreeSet<>();
  for(int i = 0; i < n; i++){
    int idx = (nums[i]-mn).size;
    bucket_min[idx] = min(bucket_min[idx],nums[i]);
    bucket_max[idx] = max(bucket_max[idx],nums[i]);  //求每个桶中最大值和最小值
    s.insert(idx);  //set保存哪个桶中有元素
  }
  int pre = 0 ,res = 0;
  for(int i= 1; i < n; i++){
    if(s.count(i)==0) continue;
    if(bucket_min[i]==Integer.MAX_VALUE || bucket_max[i]==Integer.MIN_VALUE) continue;
    res = max(res,bucket_min[i]-bucket_max[pre]);//间隔会出现在桶之间的元素
    pre =  i;
  }
  return res;
}

java leetcode--查找重复数字

给定一个数组,数组长度是N + 1,其中数字都是在1〜n的之间,但是只有一个重复的数字,但是该数字不一定重复一次。要求O(N 2)内完成,O(1)空间复杂度,不能排序。

Division algorithm
//最初设定left=1,right=n,计算mid=(left+right)/2,得到中间值,遍历数组统计小于等于mid的数字个数,如果小于等于mid则说明重复数字在mid+1~n之间,否则在1~mid之间。
public int duplicateNum(int[] nums){
  int start = 1,end = nums.length-1;
  
  while(start < end){
    int count = 0 ;
    int mid = (start+end)/2;
    for(int i  = 0; i < nums.length-1; i++){
      if(nums[i] <= mid) count++;
    }
    if(count <= mid){
      start  = mid+1;
    }else{
      end = mid;
    }
  }
  return end;
}
index-value
//利用数值与位置索引的互换关系来实现
public int indexAndValue(int [] nums){
  int min_val = 1,max_value = nums.length-1;
  int len = nums.length;
  for(int i = 0; i < nums.length;){
    if(nums[i]!=i+1 && nums[i]==nums[nums[i]-1]) return nums[i];
    else if(nums[i]!=i+1) swap(nums,i,nums[i]-1);
    else i++;
  }
}

java AlphanumComparator

Alphanum算法是一种改进的包含数字的字符串排序算法。此算法不是像标准排序那样按ASCII顺序对数字进行排序,而是按数字顺序对数字进行排序。

AlphanumComparator.java
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName: AlphanumComparator
 * @Description: The Alphanum Algorithm is an improved sorting algorithm for strings
 * containing numbers.  Instead of sorting numbers in ASCII order like
 * a standard sort, this algorithm sorts numbers in numeric order.
 *
 * The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
 *
 * Released under the MIT License - https://opensource.org/licenses/MIT
 *
 * Copyright 2007-2017 David Koelle
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 * This is an updated version with enhancements made by Daniel Migowski,
 * Andre Bogus, and David Koelle. Updated by David Koelle in 2017.
 * <p>
 * To use this class:
 * Use the static "sort" method from the java.util.Collections class:
 * Collections.sort(your list, new AlphanumComparator());
 * 
 * @Author: Aman
 * @Date: 2019-08-20 16:56
 * @Version: 1.0
 */
public class AlphanumComparator implements Comparator<String> {
    private final boolean isDigit(char ch) {
        return ((ch >= 48) && (ch <= 57));
    }

    /**
     * Length of string is passed in for improved efficiency (only need to calculate it once)
     **/
    private final String getChunk(String s, int slength, int marker) {
        StringBuilder chunk = new StringBuilder();
        char c = s.charAt(marker);
        chunk.append(c);
        marker++;
        if (isDigit(c)) {
            while (marker < slength) {
                c = s.charAt(marker);
                if (!isDigit(c)) {
                    break;
                }
                chunk.append(c);
                marker++;
            }
        } else {
            while (marker < slength) {
                c = s.charAt(marker);
                if (isDigit(c)) {
                    break;
                }
                chunk.append(c);
                marker++;
            }
        }
        return chunk.toString();
    }

    @Override
    public int compare(String s1, String s2) {
        if ((s1 == null) || (s2 == null)) {
            return 0;
        }

        int thisMarker = 0;
        int thatMarker = 0;
        int s1Length = s1.length();
        int s2Length = s2.length();

        while (thisMarker < s1Length && thatMarker < s2Length) {
            String thisChunk = getChunk(s1, s1Length, thisMarker);
            thisMarker += thisChunk.length();

            String thatChunk = getChunk(s2, s2Length, thatMarker);
            thatMarker += thatChunk.length();

            // If both chunks contain numeric characters, sort them numerically
            int result = 0;
            if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) {
                // Simple chunk comparison by length.
                int thisChunkLength = thisChunk.length();
                result = thisChunkLength - thatChunk.length();
                // If equal, the first different number counts
                if (result == 0) {
                    for (int i = 0; i < thisChunkLength; i++) {
                        result = thisChunk.charAt(i) - thatChunk.charAt(i);
                        if (result != 0) {
                            return result;
                        }
                    }
                }
            } else {
                result = thisChunk.compareTo(thatChunk);
            }

            if (result != 0) {
                return result;
            }
        }
        return s1Length - s2Length;
    }

    /**
     * Shows an example of how the comparator works.
     * Feel free to delete this in your own code!
     */
    public static void main(String[] args) {
        List<String> values = Arrays.asList("dazzle2", "dazzle10", "dazzle1", "dazzle2.7", "dazzle2.10", "2", "10", "1", "EctoMorph6", "EctoMorph62", "EctoMorph7");
        System.out.println(values.stream().sorted(new AlphanumComparator()).collect(Collectors.joining(" ")));
    }
}

java 字符串日期转换

pom.xml
<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.10.1</version>
</dependency>
TimeUtils.java
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.Date;

/**
 * @Author: zhangdeheng
 * @Date: 2019-08-20 13:43
 * @Version 1.0
 */
public class TimeUtils {

    public static String formatDate(Date date,String formatStr) {
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(formatStr);
    }

    public static Long parse(String strDate,String formatStr) {
        DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern(formatStr);
        DateTime dateTime = DateTime.parse(strDate, dateTimeFormat);
        dateTime = dateTime.plusDays(1);
        return dateTime.getMillis();
    }

    public static void main(String[] args) {
        String s = formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
        Long parse = parse(s, "yyyy-MM-dd HH:mm:ss");
        System.out.println(s+" "+parse);
    }
}

java GUI z komendami

main.java
// 
// EVENT
//

public class EventClick implements Listener {

    @EventHandler
    public void onInventoryClick(InventoryClickEvent e) {
        if(e.getView().getTitle().equalsIgnoreCase(ChatColor.AQUA + "Custom GUI")) {

            Player player = (Player) e.getWhoClicked();

            switch(e.getCurrentItem().getType()) {
                case TNT:
                    player.closeInventory();
                    player.setHealth(0.0);
                    player.sendMessage("Zabiłeś się! Brawo.");
                    break;
                case BREAD:
                    player.closeInventory();
                    player.setFoodLevel(20);
                    player.sendMessage("Jummy");
                    break;
                case GOLDEN_SWORD:
                    player.closeInventory();
                    player.getInventory().addItem(new ItemStack(Material.GOLDEN_SWORD));
                    player.sendMessage("Miecz");
                    break;
            }

            e.setCancelled(true);
        }
    }

}

//
// TWORZENIE GUI
//

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

    if(sender instanceof Player) {

        Player player = (Player) sender;
        Inventory gui = Bukkit.createInventory(player, 9, ChatColor.AQUA + "Custom GUI");

        ItemStack suicide = new ItemStack(Material.TNT);
        ItemStack feed = new ItemStack(Material.BREAD);
        ItemStack sword = new ItemStack(Material.GOLDEN_SWORD);
        ItemStack[] menuItems = {suicide, feed, sword};

        ItemMeta suicideMeta = suicide.getItemMeta();
        suicideMeta.setDisplayName(ChatColor.RED + "Suicide");
        ArrayList<String> suicideLore = new ArrayList<>();
        suicideLore.add(ChatColor.GOLD + "Kill yourself");
        suicideMeta.setLore(suicideLore);
        suicide.setItemMeta(suicideMeta);

        ItemMeta feedMeta = feed.getItemMeta();
        feedMeta.setDisplayName(ChatColor.GREEN + "Feed");
        ArrayList<String> feedLore = new ArrayList<>();
        feedLore.add(ChatColor.GOLD + "Feed yourself");
        feedMeta.setLore(feedLore);
        feed.setItemMeta(feedMeta);

        ItemMeta swordMeta = sword.getItemMeta();
        swordMeta.setDisplayName(ChatColor.BLUE + "Sword");
        ArrayList<String> swordLore = new ArrayList<>();
        swordLore.add(ChatColor.GOLD + "Give a sword");
        swordMeta.setLore(swordLore);
        sword.setItemMeta(swordMeta);
        
        gui.setContents(menuItems);

        player.openInventory(gui);
        System.out.println();
    }

    return true;
}





java Tworzenie eventu

main.java
package events;

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;

public class EventClick implements Listener {

    @EventHandler
    public void onInventoryClick(InventoryClickEvent e) {
        
    }

}