Remove null values from an ArrayList

Viewed 371

I have an ArrayList by columns, each column is a different query in my database, when showing column one "ITEMS" it shows perfect, but when showing column two "MATERIAL" it looks like the annoying null and below it shows the correct information, what happens? I have tried everything, but nothing works.

enter image description here

he tried with List.remove, List.RemoveIF, nothing works

private String[][] obtenerMatriz() {
    DetalleEntradaControlador detalleEntradaCon = new DetalleEntradaControlador();
    ArrayList<DetalleEntrada> lista = detalleEntradaCon.traerDesdeSAP();

    String matrizInfo[][] = new String[lista.size()][8];
    lista.removeAll(Collections.singleton(null));
    for (int i = 0; i < lista.size(); i++) {

        matrizInfo[i][0] = lista.get(i).getItem() + "";
        matrizInfo[i][1] = lista.get(i).getMaterial() + "";
        matrizInfo[i][2] = lista.get(i).getDescrip() + "";
        matrizInfo[i][3] = lista.get(i).getEdadPersona() + "";
        matrizInfo[i][4] = lista.get(i).getTelefonoPersona() + "";
    }
    return matrizInfo;
}

EDIT:

in my method, traerDesdeSAP, I have this Query and the .add to list....

public ArrayList<DetalleEntrada> traerDesdeSAP() {
    ArrayList<DetalleEntrada> lista = new ArrayList<DetalleEntrada>();
    DetalleEntrada detalle = null;

    try {
        Class.forName("com.sap.dbtech.jdbc.DriverSapDB");
        Conn = java.sql.DriverManager.getConnection(sapsource.getSAPSOURCE());
        s = Conn.createStatement();

        //TRAER ITEMS POR NUMERO DE DOC
        rs = s.executeQuery("...");
        while (rs.next()) {
            detalle = new DetalleEntrada();
            detalle.setItem(rs.getString(1));
            lista.add(detalle);
        }
4 Answers

you can use the java8 features for filter and collect:

List<Integer> list = Lists.newArrayList(null, 1, 2, null, 3, null);
List<Integer> listWithoutNulls = list.parallelStream()
  .filter(Objects::nonNull)
  .collect(Collectors.toList());

in your case List<DetalleEntrada> since an ArrayList is implementing a List...

List<DetalleEntrada> lista = detalleEntradaCon.traerDesdeSAP();
listaSinNulos = lista.parallelStream()
  .filter(Objects::nonNull)
  .collect(Collectors.toList());

for (int i = 0; i < lista.size(); i++) {

The error isn't in the code you pasted.

The error is in the detalleEntradaCon.traerDesdeSAP(); method.

It SHOULD be returning the equivalent of what this code would return:

var list = new ArrayList<DetalleEntrada>();
list.add(new DetalleEntrade("0001", "TR00004016", "TUB RANURADA 795111"));
list.add(new DetalleEntrade("0002", "TR00004018", "TUB RANURADA 795112"));

instead, it is returning:

var list = new ArrayList<DetalleEntrada>();
list.add(new DetalleEntrade("0001", null, null));
list.add(new DetalleEntrade("0002", null, null));
list.add(new DetalleEntrade(null, "TR00004016", null));
list.add(new DetalleEntrade(null, "TR00004018", null));
list.add(new DetalleEntrade(null, null, "TUB RANURADA 795111"));
list.add(new DetalleEntrade(null, null, "TUB RANURADA 795112"));

You have 2 options:

  1. Fix your bug. That's obviously the superior solution; you'd have to ask a new SO question if you can't figure out how to do this, and include the code of that method (and not this one; there is nothing wrong with what you pasted).

  2. Work around the bug, but this is obviously a really bad solution, and like most bug workarounds, it's difficult. However, if you aren't in control of the broken traerDesdeSAP method, this is the only way. The right solution is then to FIRST focus on fixing the bug on its own, and only then to continue with processing. Don't weave your business logic with your un-screw-up code! So, first write a separate method that collapses the list, and then continue as normal (because your code is otherwise fine, it's just that the traerDesdeSAP method is broken).

Something like:

public List<DetalleEntrada> fixBugInTraerDesdeSAP(List<DetalleEntrada> input) {
  int NUMBER_OF_FIELDS = 5;
  int size = list.size() / NUMBER_OF_FIELDS;
  var fixed = new ArrayList<DetalleEntrada>();
  for (int i = 0; i < size; i++) {
    fixed.add(new DetalleEntrada(
      input.get(NUMBER_OF_FIELDS * 0 + i).getItem(),
      input.get(NUMBER_OF_FIELDS * 1 + i).getMaterial(),
      input.get(NUMBER_OF_FIELDS * 2 + i).getDescrip(),
      input.get(NUMBER_OF_FIELDS * 3 + i).getEdadPersona(),
      input.get(NUMBER_OF_FIELDS * 4 + i).getTelefonoPersona()));
  }
  return fixed;
}

As I said, though, don't do this - go to the traerDesdeSAP method and fix it there.

Have you considered something like this?

List<String> list = new ArrayList<>();
list.add("A");
list.add(null);
list.add(null);
list.add("AB");
list.add("AC");
list.add(null);
list.add(null);
list.add(null);
list.add("AD");
list.add(null);
list.add("AE");
        
list.removeIf(o->o == null);
System.out.println(list);   

Prints

[A, AB, AC, AD, AE]

Note that the condition can be any expression that evaluates to a boolean. So you can check any and all fields of a given object.

you can use:

if(value == null) {
    return "";
}
return value;

in getters of DetalleEntrada object.

Related