Need to print last digit of string using lamda expression using java

Viewed 93

Want to print last digit from string using lamda expression. Using below code able to print complete number but want to print last digit

public static void main(String[] args) {
        List<TestDTO> studs = new ArrayList<>();
        studs.add(new TestDTO("101", "Test 101"));
        studs.add(new TestDTO("102", "Test 102"));

        Map<String, TestDTO> mapDbCardDtl = studs.stream().collect(Collectors.toMap(TestDTO::getId, Function.identity()));

        Set<String> s = mapDbCardDtl.keySet();
        System.out.println("s: " + s.toString());
    }

Below is the DTO

public class TestDTO {
    String id;
    String name;

    public TestDTO(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Output getting from above code

s: [101, 102]

Expected Output

S : [1, 2]
5 Answers

If you are interested only in printing last number from the id, which is a number written as String, then:

 List<String> s = studs.stream()
            .map(dto->dto.getId())
            .map(id -> String.valueOf(id.charAt(id.length() - 1))) // take last character and cast to String
            .collect(Collectors.toList()); 

If you want to get. last digit from name value:

 final Pattern numberPattern = Pattern.compile(".*([0-9]+).*$");
 List<String> s = studs.stream()
            // find nunmber in name
            .map(dto -> numberPattern.matcher(dto.getName()))
            .filter(Matcher::matches)
            .map(matcher -> matcher.group(1))
             // find last digit
            .map(lastNumber ->String.valueOf(lastNumber.charAt(lastNumber.length()-1)))
            .collect(Collectors.toList());

TIP:

If you wanted mapDbCardDtl to have last digit as the key, then you may fail, when more than one number ends with same digit. You will have to use overwrite merge function in toMap collector.

public static <T, K, U>
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper,
                                    BinaryOperator<U> mergeFunction)

Second solution would be using groupBy method, that will aggregate TestDTO into Map<String,List< TestDTO >>. Here the key is your digit and value : list of Dto's with this digit.

You can transform your Student's object into the last digit of id then collect in a list.

List<String> lastDigits = 
         studs.stream()
              .map(s -> s.getId().substring(s.getId().length() - 1)))
              .collect(Collectors.toList());

Note: If you collect in Set then it will contain only unique digits.

You can't use Funcion#identity and expect to have different entity with modified values. One way is to convert Map<String, TestDTO> to Map<String, String> and use the following code:

Map<String, String> mapDbCardDtl = studs
                                      .stream()
                                      .collect(Collectors.toMap(TestDTO::getId, 
                                      (testDto) -> String.valueOf(testDto.getId().charAt(testDto.getId().length() - 1))));

Set<String> s = mapDbCardDtl.keySet();
System.out.println("s: " + s.toString());

If you simply want to print the last character of the keys, add this line right before the println statement:

s = s.stream().map(x -> x.substring(x.length() - 1)).collect(Collectors.toSet());

If you actually wanted the keys in the map to only be the last character, change the stream logic to:

Map<String, TestDTO> mapDbCardDtl = studs.stream()
        .collect(Collectors.toMap(t -> t.getId().substring(t.getId().length() - 1), Function.identity()));
  1. You have already done the most part of it, Just a little set manipulation was needed.

  2. Look at the edit I made in the main method it will print your desire result.

      public static void main(String[] args) {
         List<TestDTO> studs = new ArrayList<>();
         studs.add(new TestDTO("101", "Test 101"));
         studs.add(new TestDTO("102", "Test 102"));
    
         Map<String, TestDTO> mapDbCardDtl = studs.stream().collect(Collectors.toMap(TestDTO::getId, Function.identity()));
    
         Set<String> s = mapDbCardDtl.keySet().stream()
                 .map(number -> String.valueOf(number.charAt(number.length() - 1))) // take last character and cast to String
                 .collect(Collectors.toSet());;
         System.out.println("s: " + s);
     }
    
Related