1. 程式人生 > >list 刪除元素 以一個list中的元素(或陣列中的元素)為下標

list 刪除元素 以一個list中的元素(或陣列中的元素)為下標

以一個list中的元素為下標,或者用一個數組中的元素為下標,來刪除某個list中對應下標的元素。

package cn.iponkan.test;

import static org.junit.Assert.*;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

/**
 * @author dongtangqiang
 *
 */
public class TestRemoveListElement {

  /*
   * 以一個indexList中元素為下標,刪除另一個toBeDeleteList中對應下標的元素
   * 
   * 期望在 toBeDeleteList中刪除以下元素: [2]Wednesday [5]Saturday [7]January [15]Auguest
   * [18]November
   */

  // 下標list
  List<Integer> indexList = new ArrayList<Integer>() {
    private static final long serialVersionUID = 1L;
    {
      add(2);
      add(5);
      add(5);
      add(18);
      add(7);
      add(15);
      add(7);
    }
  };

  // 待刪除list
  List<Object> toBeDeleteList = new ArrayList<Object>() {
    private static final long serialVersionUID = 1L;
    {
      add("Monday");
      add("Tuesday");
      add("Wednesday");
      add("Thursday");
      add("Friday");
      add("Saturday");
      add("Sunday");
      add("January");
      add("February");
      add("March");
      add("April");
      add("May");
      add("June");
      add("July");
      add("Auguest");
      add("September");
      add("October");
      add("November");
      add("December");
    }
  };

  // 下標陣列
  int[] indexArray = new int[] {
      2, 5, 5, 18, 7, 15, 7 };

  /**
   * 以一個list元素為下標,刪除另一個list中對應元素
   * 
   * @param indexList
   *          下標list
   * @param toBeDeleteList
   *          待刪除元素
   * @return 刪除元素後的list
   */
  public List<Object> removeElementByList(List<Integer> indexList, List<Object> toBeDeleteList)
      throws RemoveElementException {
    // 下標list去重操作
    HashSet indexSet = new HashSet(indexList);
    indexList.clear();
    indexList.addAll(indexSet);

    // 下標list長度不能大於待刪除list的長度
    if (indexList.size() > toBeDeleteList.size()) {
      throw new RemoveElementException(indexList.size(), toBeDeleteList.size());
    }

    // 下標list排序操作
    Collections.sort(indexList);

    /**
     * list移除一個元素其後的元素會自動向前移動一位,刪除一個元素,移動後,不能影響後面繼續要刪除元素的下標,從後往前刪就避免了下標變化的問題.
     */
    for (int i = indexList.size() - 1; i >= 0; i--) {
      if (indexList.get(i) >= toBeDeleteList.size()) {
        throw new RemoveElementException(i);
      }
      /**
       * 取到Integer型別的下標,會發生list集合資料刪除不了,這裡做強制型別轉換. remove(Object object);
       * remove(int index);
       */
      toBeDeleteList.remove((int) indexList.get(i));
    }

    return toBeDeleteList;
  }

  /**
   * 以一個array元素為下標,刪除另一個list中對應元素
   * 
   * @param indexArray
   * @param toBeDeleteList
   * @return
   * @throws RemoveElementException
   */
  public List<Object> removeElementByArray(int[] indexArray, List<Object> toBeDeleteList)
      throws RemoveElementException {
    HashSet indexSet = new HashSet();
    for (int i = 0; i < indexArray.length; i++) {
      indexSet.add(indexArray[i]);
    }

    Object[] array = indexSet.toArray();

    if (array.length > toBeDeleteList.size()) {
      throw new RemoveElementException(array.length, toBeDeleteList.size());
    }

    Arrays.sort(array);

    for (int i = array.length - 1; i >= 0; i--) {
      if ((int) (array[i]) >= toBeDeleteList.size()) {
        throw new RemoveElementException(i);
      }
      toBeDeleteList.remove((int) (array[i]));
    }

    return toBeDeleteList;
  }

  @Test
  public void testRemoveElementByList() {
    try {
      List<Object> result = removeElementByList(indexList, toBeDeleteList);
      Assert.assertEquals(14, result.size());
    } catch (RemoveElementException e) {
      e.printStackTrace();
      fail();
    }
  }

  @Test
  public void testRemoveElementByList2() {
    try {
      indexList.add(1);
      indexList.add(3);
      indexList.add(4);
      indexList.add(6);
      indexList.add(8);
      indexList.add(9);
      indexList.add(10);
      indexList.add(11);
      indexList.add(12);
      indexList.add(13);
      indexList.add(14);
      indexList.add(16);
      indexList.add(17);
      indexList.add(19);
      indexList.add(20);
      removeElementByList(indexList, toBeDeleteList);
      fail();
    } catch (RemoveElementException e) {
      Assert.assertTrue(e != null);
    }
  }

  @Test
  public void testRemoveElementByList3() {
    try {
      indexList.add(19);
      removeElementByList(indexList, toBeDeleteList);
      fail();
    } catch (RemoveElementException e) {
      Assert.assertTrue(e != null);
    }
  }
  
  
  @Test
  public void removeElementByArray(){
    try {
      List<Object> result = removeElementByArray(indexArray, toBeDeleteList);
      Assert.assertEquals(14, result.size());
    } catch (RemoveElementException e) {
      e.printStackTrace();
      fail();
    }
  }
  
  @Test
  public void removeElementByArray2() {
    try {
      indexArray = new int[] {1, 2,3,4, 5, 5, 6,8,9,10,11,12,13,14,15,16,17,19,18, 7, 15, 7 };
      removeElementByArray(indexArray, toBeDeleteList);
      fail();
    } catch (RemoveElementException e) {
      Assert.assertTrue(e != null);
    }
  }
  
  @Test
  public void removeElementByArray3() {
    try {
      indexArray = new int[] {3,19,7};
      removeElementByArray(indexArray, toBeDeleteList);
      fail();
    } catch (RemoveElementException e) {
      Assert.assertTrue(e != null);
    }
  }
  
}

class RemoveElementException extends Exception {
  private static final long serialVersionUID = 1L;

  public RemoveElementException() {
    super();
  }

  public RemoveElementException(int indexSize, int toBeDeletListSize) {
    super(MessageFormat.format("下標長度“{0}”,大於待刪除list的長度“{1}”", indexSize, toBeDeletListSize));
  }

  public RemoveElementException(int index) {
    super(MessageFormat.format("下標“{0}”超過待刪除list的長度", index));
  }

}